one The loading mechanism of the JVM

1. What is the class loading mechanism

Loading a class involves reading binary data from a class’s.class file into memory, placing it in the method area of the runtime data area, and then creating a java.lang. class object in the heap that encapsulates the class’s data structure in the method area. The end product of Class loading is the Class object in the heap, which encapsulates the Class’s data structure in the method area and provides the Java programmer with an interface to access the data structure in the method area.

Instead of waiting for a class to be “first actively used” before loading it, the JVM specification allows the classloader to preload a class in anticipation of it being used, and if it encounters a missing.class file or an error during preloading, The class loader must not report a LinkageError until the program first actively uses the class. If the class is never actively used by the program, the class loader will not report an error.

2. Class lifecycle

The process of class loading includes five stages: loading, verification, preparation, parsing and initialization. Of the five phases, the loading, validation, preparation, and initialization phases occur in a certain order, while the parsing phase does not, and in some cases can begin after the initialization phase, in order to support runtime binding (also known as dynamic binding or late binding) in the Java language.

Also note that the phases here start in sequence, not proceed or complete sequentially, as these phases are often intermixed with each other, often invoking or activating one phase while the other is executing.

Class loaders

From the Perspective of the Java virtual machine, there are only two different types of classloaders: launch classloaders and other loaders. (because the launcher class loader is implemented in C++ and is part of the virtual machine itself, the other loaders are implemented in Java and inherit from the abstract java.lang.ClassLoad class, and these loaders must be loaded into memory by the launcher class loader before they can load other classes.)

But from the perspective of Java developers, there are roughly four types of classloaders: startup classloaders, extension classloaders, application classloaders, and custom classloaders.

BootStrap ClassLoad:

It is responsible for loading libraries that exist in the JDK /jre/lib directory and can be recognized by the virtual machine, and launching the class loader is not directly applied by Java programs.

Extension ClassLoad:

This loader is used to load all libraries in the JDK /jre/lib/ext directory. Developers can use the extension class loader directly.

Application ClassLoad: This class loader is responsible for loading the classes specified by the user’s classpath. Developers can use this class loader directly. If the Application does not have its own custom loader, this loader is the default loader in the Application.

Custom class loaders:

A custom loader is a loader defined by users. This loader mainly pays attention to the following three points:

1. Automatically validate digital signatures before executing untrusted codes. 2. Dynamically create custom build classes that meet the specific needs of users. 3. Retrieve Java classes from specific locations, such as databases and networks.Copy the code

4. The JVM’s classloading mechanism

Full responsibility. When a Class loader is responsible for loading a Class, other classes that that Class depends on and references are also loaded by the Class loader, unless it is shown to be loaded using another Class loader.

The parent delegate, which first lets the parent loader try to load the class, and only tries to load the class from its own classpath if the parent loader fails to load the class.

The caching mechanism will ensure that all loaded classes will be cached. When a program needs to use a Class, the Class loader first looks for the Class in the cache. Only when the cache does not exist, the system will read the binary data corresponding to the Class, convert it into a Class object, and store it in the cache. This is why after Class changes are made, the JVM must be restarted for the program changes to take effect.

5. Parental delegation model

The workflow of the parental delegation model is as follows: If a class loader received the request of the class loading, it won’t try to load the first class, but give parent to complete the request, in turn up, as a result, all of the class loading request should be passed to the top finally start the class loader, only when the parent loader in the scope of its search did not find the required class, is unable to complete the loading, The child loader will try to load the class itself.

Significance of parental delegation model:

1. The system class prevents multiple copies of the same bytecode in memory. 2. Ensure the secure and stable running of Java programs.Copy the code

two JVM memory structure

The MEMORY structure of the Jvm is mainly composed of the Java heap, Java stack, local method stack, method area, and program counter.

1. Java heap:

Java heap memory is an area of memory shared by all threads whose sole purpose is to hold object instances. Almost all object instances are allocated memory here.

From the point of view of memory collection, the Java heap can be subdivided into the new generation and the old generation, since collectors are basically generational collection algorithms. The Cenozoic generation is divided into Eden region, From Survivor region and To Survivor region.

2. The method of area

The method area, like the Java heap, is an area of memory shared by all threads. Its main function is to store the class information that has been loaded by the virtual machine, constants, static variables, code compiled by the immediate compiler and so on. Although the Java Virtual Machine specification treats the method area as a logical part of the Java Heap, it also has an alias, non-heap, to separate it from the Java Heap.

However, in the HotSpot virtual machine, the method area is referred to as a “permanent generation”, which is of course not equivalent in nature, and the reason for this is that the HotSpot Virtual machine team has extended GC generation collection to the method area, in conjunction with the Java heap, forming a GC collection network.

3. Program counter

When Java files are packaged into a class, the inside of the code has been optimized, but the Java program is multithreaded, when a thread at the time of executing a program to a half, suddenly was transferred to another program execution, so how to ensure that it performs another program, such as return to come over to execute programs before, Is it possible to find exactly what point in the program was executed before? This is where the program counter comes in.

Each thread has a separate program counter that records the address of the virtual machine bytecode instructions that the thread is executing, but only for Java methods. If Native methods are used, this counter is null. This area is also the only one where the Java Virtual Machine specification does not specify any memory overflow.

4. The Java stack

Like program counters, the Java stack is a thread-private area of memory.

When a thread executes a method, it will open a stack frame in the Java stack. This stack frame will store information about the local variation table, operation stack, dynamic link, method exit and so on. So a thread will call one method after another, which will create one stack frame after another in its own Java stack, and each method will be called until the method is executed, corresponding to a stack frame in the virtual machine stack from the stack.

The Java stack, however, only serves to execute Java methods on the virtual machine.

5. Local method stack

The Native Method stack is similar to the virtual machine stack, except that the virtual machine stack performs Java methods (i.e. bytecodes) for the virtual machine, whereas the Native Method stack services the Native methods used by the virtual machine. The virtual machine specification does not mandate the language, usage, or data structure of methods in the local method stack, so specific virtual machines are free to implement it.

There are even virtual machines (such as the Sun HotSpot VIRTUAL machine) that simply merge the local method stack with the virtual machine stack. Like the virtual stack, the local method stack area throws StackOverflowError and OutOfMemoryError exceptions.

3. GC algorithm

In the JVM, program counters, The Java stack, and the local method stack are all created and killed by the thread, which is a natural way to clean up memory. This is not the case with the Java heap and method area, so our current GC garbage collector is focused on the Java heap and method area.

1. How to determine whether an object is alive or not

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

Reference count: Each object has a reference count property. When a new reference is added, the count is increased by 1. When a reference is released, the count is decreased by 1. This method is simple and does not solve the problem of objects referring to each other circularly.

Reachability Analysis: Start with GC Roots and search down the path called the reference chain. When an object is not connected to GC Roots by any reference chain, the object is proved to be unavailable. Unreachable objects.

2. Generational collection algorithm

The premise of generational collection algorithm is to determine that the life cycle of most objects is very short and the survival time is short.

The generational collection algorithm is characterized by setting the Java heap to the new generation and the old generation, so that the most appropriate algorithm can be selected according to the characteristics of different generations. (The current topic is basically HotSpot VIRTUAL machine)

New generation: objects that are ephemeral (e.g., objects referenced by local variables of a method).

Java heap is mainly divided into the new generation and the old generation. Generally, the default ratio is that the new generation occupies 1/3 of the whole Java heap, and the new generation itself will be subdivided again, in order to select a more appropriate GC collection algorithm and improve the efficiency of recycling. The Cenozoic generation is divided into Eden region, From Survivor region and To Survivor region.

When the system creates an object, it will always operate in Eden area. However, most objects will never be used again soon after creation, so they will soon become unreachable. When the area is nearly full, A YongGC will be triggered to clear these unreachable objects. The remaining surviving objects are migrated to the From Survivor region by the “copy algorithm.”

When objects From the Survivor zone die, YongGC is triggered To clean up those objects, and the remaining objects are copied To the To Survivor zone using the “replication algorithm.” In this case, the “To Survivor” area becomes the “From Survivor” area, and the previous “From Survivor” area is cleared by YongGC and becomes “To Survivor”. When an object has survived long enough in the young generation, if it has not been cleaned up by GC, it is copied to the old age through the “replication algorithm”. Alternatively, if the surviving object takes up more than 10% of the new generation’s memory during a GC run, that memory will be copied to the old generation.

Old age: objects that live longer but still die (e.g., cache objects, singletons, etc.).

The old generation stores many more objects than the young generation, and there are many large objects. It is quite inefficient to use the stop-copy algorithm to clean up the memory of the old generation. In general, the algorithm used for aged substitution is mark-collation (also known as mark-compression algorithm) algorithm, which marks the surviving objects (with references) and moves all the surviving objects towards one end to ensure the continuity of memory.

When a Minor GC occurs, the virtual machine checks whether the size of each promotion to the old age is greater than the size of the remaining space in the old age, and if so, a Full GC is triggered directly.

Permanent generation: An object that almost never dies after it is generated (e.g., loaded class information).



Ps: Finally, I recommend understanding the Java Virtual Machine: Advanced JVM Features and Best Practices by Zhiming Zhou.