1. There are three main types of loaders in Java:
Bootstrap Class Loader
- Core libraries for loading Java (String, Integer, List……) Contents in the jre/lib/rt.jar directory. C code that does not inherit from java.lang.ClassLoader.
- Loads extension class loaders and application loaders and specifies their parent class loaders.
Extensions Class Loader
- The Java virtual machine implementation automatically provides an extension directory for loading Java extension libraries (the contents of the jre/ext/*.jar directory). The class loader finds and loads Java classes in this directory.
Application Class Loader
- It loads Java classes according to the classpath path of the Java application.
Custom class loaders
- Developers can implement in-store classloaders by inheriting java.lang.ClassLoader classes to meet special requirements. Extension class loaders, application class loaders, and custom class loaders are all implemented in Java and inherit from the java.lang.ClassLoader class.
2. Class loader proxy mode: parent delegate mechanism
When a class loader receives a request to load a class, it first delegates the loading task to the parent class loader and traces back in turn. If the parent class loader can complete the loading task, it returns successfully. Only when the parent class loader cannot complete the loading task, it loads the class itself.
The parent mechanism is designed to ensure that the Java core library is type safe and that users cannot customize java.lang.Object classes.
The parent delegate mechanism is one of the proxy modes. Not all class loaders use the parent delegate mechanism. Tomcat server class loaders also use the proxy mode, but the difference is that it first tries to load a class by itself and then proxies it to the parent class loader if it cannot find it.
3. Class loading mechanism
The JVM loads the class file into memory and verifies, parses, and initializes the data, eventually producing a Java-type process that the JVM can use directly.
Class loading process: The whole life cycle of a class is divided into seven stages: loading, verification, preparation, parsing, initialization, usage, and unloading (verification, preparation, and parsing are collectively referred to as connections). The load, validate, prepare, initialize, and unload phases are in a certain order, while the parse phase is not, and in some cases, can start after initialization to support runtime binding in the Java language.
- Load: Loads the class file bytecode content into memory, converts this static data into runtime data structures in the method area, and generates a java.lang. class object representing this class in the heap as an access point to the method area class data.
- Connection: The process of merging the binaries of Java classes into the JVM’s running state. Validation: To ensure that the loaded class information complies with the JVM specification and that there are no security issues. Preparation: The stage of formally allocating memory and setting initial values for class variables (static variables), all of which will take place in the method area. Resolution: The process of replacing symbolic references in the virtual machine constant pool with direct references. (for example, String s = “aaa”, which translates the address of S to the address of “AAA”).
- Initialization: The initialization phase is the process of executing class constructor methods, which are generated by the compiler automatically collecting the assignment of all variables in a class and combining statements in a static statement block (static block). When initializing a class, if its parent has not been initialized, it needs to initialize its parent first. The virtual machine ensures that the constructor methods of a class are locked and synchronized correctly in a multithreaded environment. When accessing the static field of a Java class, only classes that actually declare the static variable are initialized.
4. The loading process of classes is divided into active reference and passive reference of classes
An active reference to a class (class initialization must occur) :
- New An object of a class
- Call static members of the class (except final constants) and static methods
- Make a reflection call to the class using the methods of the java.lang.Reflect package
- When initializing a class, initialize its parent class first if the parent class is not already initialized
- When executing a program, always start the class of the main method
A passive reference to a class (class initialization does not occur) :
- When accessing a static variable, only the class that actually declared the static variable is initialized. (Referring to a static variable of the parent class by subclass does not cause subclass initialization.)
- A[] A = new A[10];
- Referring to constants (final types) does not trigger initialization of this class (constants are stored in the calling class’s constant pool at compile time)
5. The loading order of Java classes
- Static initialization blocks, static member variables, and static methods are initialized when a Java class is first loaded by the VIRTUAL machine
- An instance of the class is created only when the new method is called
- Class instance creation: first the initialization block part of the parent class, then the constructor of the parent class, then the initialization block of the subclass, and finally the constructor of the subclass
- When a class instance is destroyed, the subclass part is destroyed first and then the parent part is destroyed.
6. Java program execution process
Java source code files (.java) are first compiled into bytecode files (.class) by Java. The bytecode files of each class are then loaded by the JVM class loader and sent to the JVM execution engine for execution.
7. JVM region division
JVM regions can be divided by thread into thread-isolated and thread-shared parts. Thread-isolated means that these regions are thread-unique and are allocated to each thread, including program counters, Java stacks, and local method stacks. Threads share method areas and heap.
Program Counter Register
Because in the JVM, threads through the threads to take turns to switch for CPU execution events, so at any specific moment, a CPU can only execute one thread in the instruction, in order to be able to make each thread in the thread or able to switch back to the previous program execution, each thread needs to have their own independent of the program counter, And can not be interfered with each other, otherwise it will affect the normal execution order of the program. So program counters are private to each thread. According to the JVM specification, if a thread is executing a non-native method, the program counter stores the address of the instruction that is currently being executed. If the thread executes a native method, the value stored in the program counter is undefined.
Java Stack
The Java stack is also called the Java Vitual Machine stack. The Java stack stores a stack frame, each stack frame corresponds to a method to be called. The stack frame includes local variables, perand stack, a reference to the run-time constant pool of the class to which the current method belongs, the method return address, and some additional information.
Native method Stack
The function and principle of the local method stack are very similar to the Java stack, except that the Java stack serves to execute Java methods, whereas the local method stack serves to execute local methods. The JVM specification does not mandate the implementation of native methods or data structures, and the virtual machine is free to implement them. The Hotsopt virtual machine directly combines the native method stack with the Java stack.
Method Area
The method area is a very important area in the JVM, shared by threads along with the heap. In the method area, information about each class (including the name of the class, methods, and field information), static variables, constants, and the compiled code for the compiler are stored. A very important part of the method area is the runtime constant pool, which is the runtime representation of the constant pool for each class or interface that is created after the class or interface is loaded into the JVM. Of course, only the contents of the Class file constant pool can be entered into the runtime constant pool. At run time, new constants can be added to the runtime constant pool, such as the String intern method. You can think of the method region as the permanent generation.
Heap (Heap)
The Java heap is used to store objects and arrays, references to which are stored in the Java stack. The heap is shared by all threads, and there is only one heap in the JVM.
In Java, the heap is divided into two distinct regions: Young and Old.
The Cenozoic is divided into three regions: Eden and two surviving regions.
The purpose of this partitioning is to enable the JVM to better manage objects in heap memory, including memory allocation and reclamation.
The new generation mainly stores newly created objects and objects that have not yet entered the old age. The old age stores objects that are still alive after several Minor Generation GC.
Method area mainly stores the data between classes and the relationship between classes, this part of the data is loaded into memory, basically will not change, but later method area will also be recycled, recycling conditions are very harsh; Data in the Java heap is basically dead and recycled when it’s used; The data in the Java stack and the local method stack meet the principle of “first in, last out”. To obtain the elements at the bottom of the stack, the elements at the top of the stack must be removed from the stack with a recovery rate of 100%. The program counter is the only area that does not run out of memory.
Reference 8.
In Java, an object without a reference to it is considered garbage.
- Java memory management is divided into memory allocation and memory reclamation without programmer involvement.
- Garbage collection depends on whether an object has a reference to it. References to Java objects include strong references, soft references, weak references, and virtual references.
- Strong reference: Creates an object and assigns it to a reference variable. Strong references with reference variables are never reclaimed, even when out of memory.
- SoftReference: a device uses the SoftReference class. If the system has enough memory, no SoftReference is reclaimed. A SoftReference object is similar to a strong reference object, but a SoftReference object is reclaimed if the system has insufficient memory.
- WeakReference: implemented through the WeakReference class, it is highly uncertain because garbage collection will reclaim the weakly referenced objects every time.
- Virtual references: Both soft and weak references can be used alone. Virtual references cannot be used alone and must be associated with reference queues. The function of virtual reference is to track the status of the object being garbage collected. The program can know whether the virtual reference object is about to be garbage collected by detecting whether the virtual reference queue associated with the virtual reference already contains the specified virtual reference. It allows you to know when an object is removed from memory.
Weaker references in Java mean fewer restrictions on the garbage collector and easier for objects to be collected.
9. Recycling
1. Reference counter algorithm: When creating objects, for the object in the stack space allocated in the address, will produce a reference counter at the same time, the reference count + 1 at the same time, when there is a new reference, reference counter to + 1, and when one of the references to destroy, reference counter – 1, when the reference count is reduced to 0, mark the object has no reference, It can be recycled. But this algorithm does not apply when the code has the following situation: objA points to objB, and objB points to objA, so that after all other references have disappeared, objA and objB still have a reference to each other that cannot be reclaimed, but in fact there are no additional references to either object, and they are already garbage.
ObjA.obj = ObjB; ObjB.obj = ObjA;Copy the code
2, Root search algorithm (GC Root) : all the reference relationship as a diagram, starting from a node GC Root, find the corresponding reference node, found after this node, continue to look for reference from the node, when all the reference node seeking to end, the rest of the nodes is considered not by reference to the node, the useless nodes. Objects that can be used as GC Root in Java are referenced objects in the virtual machine stack, objects referenced by static properties in the method area, objects referenced by constants in the method area, and objects referenced by local method stacks.
3. What algorithm is used to recycle the collected garbage?
- Mark-clear algorithm: scan from the root set and mark the surviving objects. After marking, scan the unmarked objects in the whole space for recycling. The mark-clear algorithm does not need to move objects and only processes the non-viable objects, which is extremely efficient in the case of a large number of viable objects. However, because the mark-clear algorithm directly reclaims the non-viable objects, it will cause memory fragmentation.
- Replication algorithm (for the new generation) : The replication algorithm scans from the root set and copies the living objects to a new, unused space. This algorithm is extremely efficient when there are few living objects in memory, but it brings the cost of a memory swap space for object movement. In the replication algorithm, only Eden region and one surviving region are used to store data in the new generation. When the surviving region reaches saturation, the surviving objects in the surviving region are moved to another surviving region.
- Mark-tidy algorithm (used in the old era) : The mark-tidy algorithm and the mark-clear algorithm use the same way to mark the object, but the clearing is different. After the space occupied by the non-viable object is reclaimed, all the viable objects are moved to the left free space and the corresponding pointer is updated. Fixed memory fragmentation.
- Generation recycling mechanism:
New generation: Most newly created objects are allocated here. Since most objects become unreachable soon after creation, many objects are created in the new generation and then disappear. The process by which this region of the object disappears is called “minor GC”.
There are three Spaces, including one Eden and two Survivors. The execution sequence of each space is as follows:
1. Most newly created objects are stored in the Garden of Eden space.
2. After performing a GC in the Eden space, the surviving object is moved to one of the survivor Spaces.
3. After GC is performed in Eden space, the surviving objects are stacked in the same survivor space.
4. When a survivor space is saturated, surviving objects will be moved to another survivor space, and then the saturated survivor space will be emptied.
5. Repeat the above steps several times and the surviving objects will be moved to the old age.
Old age: Objects that do not become unreachable and survive the new generation will be copied here and take up more space than the new generation. And because of its relatively large space, there are far fewer GCS occurring in the old age than in the Cenozoic. The process by which objects disappear from the old age is called the “major GC.”
Permanent generation: Also known as method area, used to hold class constants as well as string constants. Therefore, this area is not used to permanently store objects that have survived from the old age. GC can also occur in this region, and GC events that occur in this region are also referred to as major GC.