I was asked by the interviewer about the stinky performance optimization of JVM. Don’t you know? Recommend collection!

One, JVM performance optimization topic

1. Java class loading process

Java class loading requires 7 processes:

1.1. Loading

Loading is the first process of class loading. At this stage, three things will be completed:

  • Obtain the binary stream of a class by its fully qualified name.
  • Convert the static storage structure in the binary stream into a method to run-time data structure.
  • Generate the Class object of this class in memory as the data access entry of this class.

1.2. Verification

The purpose of verification is to ensure that the information in the byte stream of the Class and file does not harm the virtual machine. At this stage, the following four verifications are mainly completed:

  • File format verification: Verify whether the byte stream conforms to the file specification, such as whether the major and minor version numbers are within the current virtual machine range, and whether the constants in the constant pool have unsupported types.
  • Metadata verification: Semantic analysis of the information described by the bytecode, such as whether this class has a parent class, whether it integrates a class that is not inherited, etc.
  • Bytecode verification: It is the most complicated stage in the entire verification process. Through the analysis of the verification data flow and control flow, it is determined whether the program semantics is correct, mainly for the verification of the method body. Such as: whether the type conversion in the method is correct, whether the jump instruction is correct, etc.
  • Symbol reference verification: This action occurs in the subsequent parsing process, mainly to ensure that the parsing action can be executed correctly.

1.3. Preparation

The preparation stage is to allocate memory for the static variables of the class and initialize it to the default value. These memory will be allocated in the method area. The memory of instance variables in the class is not allocated in the preparation phase. The instance variables will be allocated in the Java heap along with the object when the object is instantiated.

 public static int value=123;//在准备阶段value初始值为0 。在初始化阶段才会变为123 。

1.4. Analysis

This stage mainly completes the conversion action from symbol reference to direct reference. The parsing action is not necessarily before the initialization action is completed, it may also be after the initialization.

1.5. Initialization

The last step of class loading during initialization, the previous class loading process, except that the user application can participate in the loading stage through a custom class loader, the rest of the actions are completely dominated and controlled by the virtual machine. At the initialization stage, the java program code defined in the class is actually executed.

1.6. Use

1.7. Uninstall

2. Java memory allocation

  • Register: We have no control.
  • Static domain: static members defined by static.
  • Constant pool: (final) constant values ​​and some text-modified symbol references (fully qualified names of classes and interfaces, names and descriptors of fields, methods and names and descriptors) that are determined and saved in the .class file at compile time .
  • Non-RAM storage: permanent storage space such as hard disks.
  • Heap memory: The objects and arrays created by new are managed by the automatic garbage collector of the Java virtual machine, and the access speed is slow.
  • Stack memory: basic types of variables and object reference variables (access addresses of the heap memory space) are fast and can be shared, but the size and lifetime must be determined and lack flexibility.

2.1. What is the structure of the Java heap? 2 What is the permanent generation in the heap?

The heap of the JVM is the runtime data area, and all instances and arrays of classes are allocated memory on the heap. It
is created when the JVM starts. The heap memory occupied by the object
is collected by the automatic memory management system, which is the garbage collector.
Heap memory is composed of live and dead objects. The surviving objects are accessible by the application and will not be garbage collected. Dead objects are objects that are not accessible by the application and have not been collected by the garbage collector. Until the garbage collector collects these objects, they will occupy the heap memory space.

3. Describe the principle and mechanism of JVM loading Class files 2

The Java language is a dynamic, interpreted language. Classes can only run after being loaded into the JVM. When running the specified program, the JVM will
load the compiled .class files into memory according to requirements and certain rules, and organize them into a complete Java application. This loading process is completed by the class loader, specifically, it is implemented by the ClassLoader and its subclasses. The class loader itself is also a class, its essence is to read the class file from the hard disk to the memory.
Class loading methods are divided into implicit loading and explicit loading. Implicit loading means that when the program uses new methods to create objects, it will implicitly call the class loader to load the corresponding class into the JVM. Display loading refers to loading the required class into the JVM by directly calling the class.forName() method.

Any engineering project is composed of many classes. When the program starts, only the required classes are loaded into the JVM. Other classes will only be loaded when they are used. This method can speed up the loading speed on the one hand. On the other hand, it can save the memory overhead when the program is running. In addition, in the Java language, each class or interface corresponds to a file.class, these files can be seen as a unit that can be dynamically loaded, so when only some classes are modified, only the changed ones need to be recompiled The class can be used without recompiling all files, thus speeding up compilation.
In the Java language, the loading of classes is dynamic. It does not load all classes at one time and then run, but to ensure that the basic classes (such as base classes) that the program runs are completely loaded into the JVM. As for other classes, It will be loaded when needed.
The main steps of class loading:

  • load. Find the corresponding class file according to the search path, and then import it.
  • link. The link can be divided into 3 small steps:
  • Check, check the correctness of the class file to be loaded.
  • Prepare to allocate storage space for static variables in the class.
  • Resolve, convert symbol references to direct references (this step is optional)
  • initialization. Perform initialization work on static variables and static code blocks.

4. What is GC? Why is there a GC?

GC means garbage collection (GabageCollection). Memory processing is a place where programmers are prone to problems. Forgetting or wrong memory recycling can cause instability or even crash of the program or system. The GC function provided by Java can automatically monitor whether the object exceeds the effect. The domain thus achieves the purpose of automatically reclaiming memory. The Java language does not provide a display operation method to release allocated memory.

5. Briefly describe the Java garbage collection mechanism)

In Java, the programmer does not need to release the memory of an object explicitly, but is executed by the virtual machine itself. In the JVM, there is a garbage collection thread. It is low-priority and will not be executed under normal circumstances. It will only be triggered when the virtual machine is idle or the current heap memory is insufficient. Reference the objects and add them to the collection to be recycled for recycling.

6. How to judge whether an object is alive? (or how to judge GC objects)

There are two ways to determine whether an object is alive:

6.1. Reference counting

The so-called reference counting method is to set a reference counter for each object. Whenever there is a reference to this object, the counter is incremented by one, and when the reference is invalid, the counter is decremented by one. When the reference counter of an object is zero, it means that the object is not referenced, that is, the "dead object", and will be garbage collected. The
reference counting method has a defect that it cannot solve the circular reference problem, that is, when the object A is referenced Object B and Object B refer to Object A, then the reference counters of Object A and Object B are not zero at this time, and garbage collection cannot be completed. Therefore, mainstream virtual machines have not adopted this algorithm.

6.2. Reachability algorithm (reference chain method)

The idea of ​​this algorithm is to search downwards from an object called GC Roots. If there is no reference chain linking an object to GC Roots, then this object is not available. The objects that can be used as GC Roots in Java are as follows:

  • Objects referenced in the virtual machine stack
  • Objects referenced by static properties of the method area • Objects referenced by the constant pool of the method area
  • Objects referenced by the local method stack JNI
    Although these algorithms can determine whether an object can be recycled, when the above conditions are met, an object may not necessarily be recycled. When an object is not reachable to the GC Root, the object will not be recovered immediately, but is in a phase of death with reprieve. To be truly recovered, it needs to go through two markings.
    If the object is not connected to the GC in the reachability analysis Root's reference chain, then it will be marked for the first time and a filter is performed. The condition of the filter is whether it is necessary to execute the finalize() method. When the object does not cover the finalize() method or has been called by the virtual machine, then it is considered unnecessary. If it is necessary for the object to execute the finalize() method, then the object will be placed in a pair queue called F-Queue, and the virtual machine will
    trigger a Finalize() thread to execute. This thread is low-priority and virtual The machine will not promise to wait for it to finish running. This is because if finalize() is slow or deadlock occurs, it will cause the F-Queue queue to wait all the time, causing the memory recovery system to crash. The GC will mark the object in the F-Queue for the second time. At this time, the object will be removed from the "Recycling" collection, waiting for recycling.

7. The advantages and principles of garbage collection) and consider 2 recycling mechanisms)

A notable feature of the Java language is the introduction of a garbage collection mechanism, which makes C++ programmers the most troublesome memory management problem easily solved. It makes Java programmers no longer need to consider memory management when writing programs. Due to a garbage collection mechanism, objects in Java no longer have the concept of "scope", and only object references have "scope". Garbage collection can effectively prevent memory leaks and effectively use available memory. The garbage collector usually runs as a separate low-level thread. Under unpredictable circumstances, the objects in the memory heap that have died or have not been used for a long time are cleaned and recycled. The programmer cannot call the garbage collector in real time to Object or all objects are garbage collected.
The recycling mechanism includes generational copy garbage collection, marked garbage collection, and incremental garbage collection.

8. What is the basic principle of the garbage collector? Can the garbage collector reclaim memory immediately? Is there any way to proactively notify the virtual machine for garbage collection?

For the GC, when the programmer creates an object, the GC starts to monitor the address, size, and usage of the object. Generally, GC uses a directed graph to record and manage all objects in the heap. In this way, determine which objects are "reachable" and which objects are "unreachable". When the GC determines that some objects are "unreachable", the GC is responsible for reclaiming these memory spaces. can. The programmer can manually execute System.gc() to notify the GC to run, but the Java language specification does not guarantee that the GC will be executed.

9. Will there be a memory leak in Java? Please describe briefly)

The so-called memory leak means that an object or variable that is no longer used by the program has been occupied in memory. There is a garbage collection mechanism in Java, which can ensure that when an object is no longer referenced, that is, when the object becomes an orphan, the object will be automatically removed from the memory by the garbage collector. Because Java uses a directed graph for garbage collection management, it can eliminate the problem of reference cycles. For example, there are two objects that refer to each other. As long as they are unreachable to the root process, the GC can also recycle them, such as the following code You can see the memory recovery in this situation:

*/
public static void main(String[] args) throws IOException {
    
    
// TODO Auto-generated method stub try { gcTest();
} catch (IOException e) {
    
    
// TODO Auto-generated catch block e.printStackTrace();
}
System.out.println("has exited gcTest!"); System.in.read();
System.in.read(); System.out.println("out begin gc!"); for(int i=0;i<100;i++)
{
    
    
System.gc(); System.in.read(); System.in.read(); }
}
private static void gcTest() throws IOException {
    
     System.in.read();
System.in.read();
Person p1 = new Person(); System.in.read(); System.in.read();
Person p2 = new Person(); p1.setMate(p2); p2.setMate(p1);
System.out.println("before exit gctest!"); System.in.read(); System.in.read();
System.gc(); System.out.println("exit gctest!");
}
private static class Person {
    
    
byte[] data = new byte[20000000]; Person mate = null; public void setMate(Person other) {
    
    
mate = other;
}
}
}

Memory leaks in Java: long-lived objects hold references to short-lived objects and memory leaks are likely to occur.Although short-lived objects are no longer needed, they are because long-lived objects hold their references. It can't be recycled. This is the scene of memory leaks in Java.In layman's terms, the programmer may create an object, and the object will never be used in the future, but the object has been referenced, that is, the object is useless but cannot Reclaimed by the garbage collector, this is a memory leak that may occur in java. For example, in the cache system, we load an object in the cache (for example, in a global map object), and then never use it. This object has been referenced by the cache, but is no longer used.
To check for memory leaks in Java, you must let the program execute the various branch situations completely to the end of the program, and then see whether an object has been used, if not, then you can determine that the object is a memory leak.
If the method of an instance object of an outer class returns an instance object of an inner class, the inner class object is long-term referenced, even if the outer class instance object is no longer used, but because the inner class persists the outer class instance object, this External class objects will not be garbage collected, which will also cause memory leaks.
The following content comes from the Internet (the main feature is to clear an element in the stack, not to completely remove it from the array, but to reduce the total number of storage. I can write better than this, and I am removing an element At the same time, let it disappear from the array by the way, and set the value of the position of that element to null):
I really can't think of a more classic example than that stack, so I have to quote other people's examples, the following The example was not what I thought of, but I saw it in the book. Of course, if I didn't read it in the book, I might think of it myself after a while, but at that time I said it was what I thought of and no one believed it.

public class Stack {
    
    
private Object[] elements=new Object[10]; private int size = 0
;
public void push(Object e){
    
     ensureCapacity(); elements[size++] = e;
}
public Object pop(){
    
    
if( size == 0) throw new EmptyStackException(); return element

 s[--size];
}
private void ensureCapacity(){
    
     if(elements.length == size){
    
     Object[] oldElements = elements;
elements = new Object[2 * elements.length+1]; System.arraycopy (oldElements,0, elements, 0,
size);
}
}
}

The above principle should be very simple, if the stack adds 10 elements, and then all pop up, although the stack is empty, there is nothing we want, but this is an object that cannot be recycled, this only meets the two memory leaks Condition: Useless and cannot be recycled. But even the existence of such a thing does not necessarily lead to any consequences. If this stack is used less, it will waste a few K of memory. Anyway, our memory is all on G, where will it affect it? This thing will be recycled soon, what does it matter? Let's look at two examples.

public class Bad{
    
    
public static Stack s=Stack(); static{
    
     s.push(new Object());
s.pop(); //这里有—个对象发生内存泄露
s.push(new Object()); //上面的对象可以被回收了,等于是自 愈了
}
}

Because it is static, it will exist until the program exits, but we can also see that it has a self-healing function, that is, if your Stack has at most 100 objects, then at most only 100 objects cannot be recycled. In fact, this should be very It is easy to understand that Stack holds 100 references inside, and the worst case is that they are all useless, because once we put a new initiative, the previous references will naturally disappear!
Another case of memory leakage: when an object is stored in After the HashSet collection, the fields in the object that participate in the calculation of the hash value cannot be modified. Otherwise, the modified hash value of the object will be different from the hash value when it was originally stored in the HashSet collection. In this case, even if the contains method uses the current reference of the object as a parameter to retrieve the object from the HashSet collection, it will return the result that the object cannot be found, which will also make it impossible to delete the current object from the HashSet collection separately, causing memory leaks .

10. Deep copy and shallow copy)

Simply put, it is copying and cloning.

Person p=new Person(“张三”);

Shallow copy is simply assigning values ​​to data members in the object. If there are dynamic members or pointers, an error will be reported.
Deep copy is to reopen memory space for dynamic members or pointers existing in the object.

11. What will System.gc() and Runtime.gc() do?

These two methods are used to prompt the JVM to perform garbage collection. However, whether to start immediately or delay garbage collection depends on the JVM.

12. When is the finalize() method called? What is the purpose of the destructor (finalization)?

When the garbage collector (garbage colector) decides to recycle an object, it will run the finalize() method of the object. But unfortunately in Java, if the memory is always sufficient, then the garbage collection may never proceed, that is to say, filalize () may never be executed, obviously it is unreliable to count on it to do finishing work. So what exactly does finalize() do? Its main purpose is to reclaim memory allocated by special channels. Java programs have a garbage collector, so under normal circumstances, memory problems don't need programmers to worry about. But there is a JNI (Java Native Interface) that calls non-Java programs (C or C++), and the job of finalize() is to reclaim this part of the memory.

13. If the object reference is set to null? Will the garbage collector release the memory occupied by the object immediately?

No, in the next garbage collection cycle, this object will be recyclable.

14. What is distributed garbage collection (DGC) and how does it work?

DGC is called distributed garbage collection. RMI uses DGC to do automatic garbage collection. Because RMI contains references to remote objects across virtual machines, garbage collection is difficult. DGC uses a reference counting algorithm to provide automatic memory management for remote objects.

15. What is the difference between a serial collector and a throughput collector?

The throughput collector uses a parallel version of the new-generation garbage collector, which is used for medium-scale and large-scale data applications. The serial collector is sufficient for most small applications (about 100M of memory required on modern processors).

16. In Java? When can an object be garbage collected?

When the object becomes inaccessible to the application currently using the object, the object can be recycled.

17. Briefly describe the Java memory allocation and recovery strategy and Minor GC and Major GC)

  • Objects are allocated first in the Eden area of ​​the heap
  • Big objects enter the old age directly
  • Long-lived objects will directly enter the old age.
    When there is not enough space in the Eden area for allocation, the virtual machine executes a Minor GC. Minor GC usually occurs in the Eden area of ​​the young generation. Objects in this area have a short lifetime, and Gc tends to occur more frequently, and the recovery speed is faster; Full GC/Major GC occurs in the old generation, and under normal circumstances, it triggers the old generation Minor GC will not be triggered during GC, but through configuration, a Minor GC can be performed before Full GC, which can speed up the recovery speed of the old generation.

18.Will garbage collection occur in the permanent generation of the JVM?

Garbage collection does not occur in the permanent generation. If the permanent generation is full or exceeds the critical value, a full garbage collection (Full GC) will be triggered.
Note: In Java 8, the permanent generation has been removed, and a new native memory
area called the metadata area has been added .

19.What are the methods of garbage collection in Java?

Mark-Clear: This is the most basic of the garbage collection algorithm. According to the name, it can be known. Its idea is to mark which objects to be recycled, and then collect them uniformly. This method is simple, but there are two main problems:

  1. The efficiency is not high, and the efficiency of marking and removal is very low;
  2. A large number of discontinuous memory fragments will be generated, causing the program to trigger a GC action in advance due to insufficient continuous memory when allocating larger objects in the future.
    Copy algorithm: In order to solve the efficiency problem, the copy algorithm divides the available memory into two equal parts according to the capacity, and then only uses one of them at a time. When one memory is used up, the surviving objects are copied to the second memory. , And then clear the first block of memory at one time, and then copy the objects on the second block to the first block. But in this way, the cost of memory is too high, and general memory is basically wasted every time.
    So the algorithm is improved, the memory area is no longer divided by 1:1, but the memory is divided into 8:1:1 three parts, the larger one is assigned to the Eden area, and the rest are two smaller ones. The memory area is called Survior area. The Eden area will be used first every time. If the Eden area is full, the objects will be copied to the second memory area, and then the Eden area will be cleared. If there are too many surviving objects at this time that Survivor is not enough, these objects will be passed through The distribution guarantee mechanism is copied into the old age. (The java heap is divided into the new generation and the old generation)
    Marking-finishing: This algorithm is mainly to solve the problem of marking-clearing and generating a large number of memory fragments; when the object survival rate is high, it also solves the efficiency problem of the replication algorithm. The difference is that when the object is cleared, the recyclable object is now moved to one end, and then the object outside the end boundary is cleared, so that no memory fragmentation will occur.
    Generational collection: Most of the current virtual machine garbage collection uses this method. It divides the heap into the young generation and the old generation according to the life cycle of the object. In the new generation, due to the short lifetime of objects, a large number of objects will die every time they are recycled, so the replication algorithm is used at this time. Objects in the old age have a higher survival rate, and there is no extra space for allocation guarantees.

20. What is a class loader? What are the class loader?

The code block that realizes the access to the binary byte stream of the class through the permission of the class is called the class loader. There are mainly four types of loaders:

  • BootstrapClassLoader is used to load the Java core class library, which cannot be
    directly referenced by Java programs.
  • Extensions class loader: It is used to load Java extension libraries. The implementation of the Java virtual machine will provide an extension library directory. The class loader finds and loads Java classes in this directory.
  • System class loader (system class loader): It loads Java classes according to the CLASSPATH of Java applications. Generally speaking, Java application classes are loaded by it. It can be obtained by ClassLoader.getSystemClassLoader().
  • User-defined class loader is implemented by inheriting java.lang.ClassLoader class.

21. The parent delegation model mechanism of the class loader?

When a class receives a class loading request, it will not load the class by itself, but delegate it to the parent class, which will be loaded by the parent class. If the parent class cannot be loaded at this time, it will be fed back to the subclass and the subclass To complete the loading of the class.

Guess you like

Origin blog.csdn.net/Java_Yhua/article/details/111220478