The JVM components are shown in Fig
The main components of the JVM include runtime data areas, execution engines, local interfaces, and local method libraries. This article mainly shares the class loading mechanism of JVM.
In j**a, each class or interface is compiled by the compiler to generate a corresponding. class file.
The class loading mechanism refers to what will be compiled and generated. The class file (binary data) is loaded into memory, and the data is verified, parsed, and initialized. Finally, the class information is saved in the method area, and a corresponding class object is generated.
There is no clear time for class loading, and it is generally loaded when the class is initialized.
Class Initialization When:
1) Initialize when creating an object with the new keyword, reading or setting a static field of a class, and calling a static method of a class.
2) Use j**alang.The method of the reflect package initializes the class when it makes a reflection call.
3) When initializing a class, if its parent class has not been initialized, you need to initialize its parent class first.
4) When the virtual machine starts, initialize the class where the main() method is located.
5) In JDK8, if the interface defines the default method, when the implementation class of the interface is initialized, the interface needs to be initialized before the implementation class is initialized.
The entire life cycle of a class goes through seven stages: loading, validating, preparing, parsing, initializing, using, and unloading. The loading process of a class mainly consists of five stages: loading, verification, preparation, parsing, and initialization.
As shown in Fig
Note: The five stages of the class loading process are not strictly sequential, they are mixed and intersected with each other to finally complete the loading and initialization of the class (e.g., in the loading phase, it is necessary to verify the correctness of the bytecode; In the parsing phase, you need to verify the correctness of the symbolic references).
During the loading phase, the classloader loads the class based on its fully qualified name.
Loading steps: 1) Find the corresponding class file by the fully qualified name of the class.
2) Read the binary data from the class file into memory and convert it into a runtime data structure in the method area.
3) Generate a class corresponding j**a. in the heaplang.Class object (class object contains: class name, class access modifier, class method, class member variable, etc.) as the access point to the data in the method area.
After the loading phase is completed, the linking phase consists of three phases: validation, preparation, and parsing.
The main function of the verification phase is to ensure that the loaded class information conforms to the JVM specification and does not affect the security of the virtual machine itself.
Verification content: File format verification: verifies whether the byte stream conforms to the specifications of the class file format.
Metadata verification: Semantic analysis of the metadata information described by bytecode to ensure that the metadata information conforms to the j**a language specification.
Bytecode verification: Verify and analyze the method body of a class to ensure that the method is valid and logically correct.
Symbol Reference Verification: Verify the correctness of the symbol reference when the symbol reference is converted to a direct reference in the parsing phase, such as whether the fully qualified name of the symbol reference can find the corresponding class, and whether the classes, fields, and methods in the symbol reference are allowed to be accessed by the current class.
The validation phase is not necessary, and you can reduce the loading time of the class by setting the -xverify:none parameter to turn off validation of the class.
The preparation phase allocates memory for class variables (static variables) and sets default initial values.
Note: 1) The preparation stage only allocates memory for static variables, and class instance variables allocate memory when the object is instantiated.
2) The initial value refers to the default value of the variable data type, not the value explicitly assigned in j**a**. If the variable is modified to a constant by final, the initial value is the value explicitly given in j**a**. Such as:
public static int age = 20, the default default value set by age in the preparation phase is 0 instead of 20.
Public final static int age = 20, the default default value set in the preparation phase is 20 instead of 0.
3) In jdk8 the perpetual generation was abolished, the method area became a logical area, and the memory of the class variables was allocated in the heap (in jdk7 and before, the memory of the class variables was allocated in the permanent generation).
During the parsing phase, the virtual machine replaces the symbolic reference in the constant pool in the class file with a direct reference, i.e., the loaded target class is formally linked to the class it references.
Note: Symbolic references: J**A** does not know the type of the final reference and where it should point in memory at compile time, and will use a symbolic reference to represent the target of the reference. The form of the symbol reference is clearly defined in the j**a virtual machine specification, and the symbol reference can be any value, as long as the target can be located through this value.
Direct Reference: Refers to a pointer or handle that can directly or indirectly point to a target memory location.
Constant Pool: A static constant pool: a static storage structure in a class file. For example, the fully qualified name of a class or interface, the field name and descriptor, the method name and descriptor, the method handle, the method type, etc. Static constant pools are stored in the method area.
Runtime pool: stores the runtime data structure parsed by the class file. The running constant meter pool is stored in the method area.
String Constant Pooling: String constant pooling is implemented through a stringtable class (default size is 1009) to store string constants (consisting of characters). String constant pools are stored in the heap.
The initialization process is the process of executing the classconstructor() method.
Once initialized, the class variable is assigned a value explicitly defined in j**a**, and a static block in the class is executed.
Note: The class constructor() method is generated by the compiler's automatic collection of assignment actions for all class variables in the class and the merger of statements in static blocks.
It's the class constructor, it's the instance constructor.
When initializing a class, if you find that its parent class has not been initialized, you need to trigger the initialization of its parent class first.
There are three types of classloaders:
BootstrapClassLoader: Responsible for loading the jar package in the lib directory, or the path specified by the parameter -xbootclasspath. For example, jre lib rtjar. Implemented by C++, not a classloader subclass.
extclassloader: responsible for loading the lib ext directory or j**aext.The jar package in the directory specified by the dirs. Implemented by j**a**.
AppClassLoader: The JAR package responsible for loading the ClassPath path, i.e., the application JAR package. Implemented by j**a**.
In addition, developers can customize the classloader.
Custom classloader use cases
Load from non-standardFor example, if the bytecode is placed in the database or the cloud, you can use a custom class loader to load the class from the specified **.
EncryptionIf you need to encrypt ** to prevent decompilation, you can first encrypt the compiled ** with a certain encryption algorithm, and then customize the class loader, and decrypt the class before loading it.
Custom classloader implementation
The custom classloader needs to inherit the classloader class or urlclassloader, and override its findclass(string name) method, and call defineclass() in the findclass() method to generate the corresponding class instance.
Custom classloader example:
** author Nanqiu * Custom classloader * @slf4jpublic class customclassloader extends classloader ** Find the specified class according to the class name to load * param name Class name * return class object * throws classnotfoundexception No specified class exception found * @override Protected Class FindClass(String Name) Throws ClassNotFoundException Else Catch (Exception E) If the parent classloader is loaded successfully, the class object if(cls!) is returned=null)else else } ** Convert the bytecode file to a byte array based on the class name * param name class name * return byte array * private byte getclassdate(string name) baosflush();Return the byte array corresponding to the bytecode file return baostobytearray();catch (exception e) return null; }Parental delegation mechanismLoad the processThe parental delegation mechanism loads the flow, as shown in the diagram
Processing process: 1) When you need to load a class (regardless of the custom class loader), first check whether the class has been loaded in the appclassloader, if it has been loaded, return the class object corresponding to the class, if not, give the request to the parent class loader (extclassloader) to try to load.
2) Check whether the class has been loaded in the extclassloader, if it has been loaded, return the class object corresponding to the class, if it is not loaded, then hand over the request to the parent class loader (bootstrapclassloader) to try to load.
3) Check whether the class has been loaded in the bootstrapclassloader, if it has been loaded, the class object corresponding to the class will be returned, if it is not loaded, the bootstrapclassloader will try to load the class. If the load is successful, the class object corresponding to the class is returned. If the load fails, the request is sent to the extclassloader to try to load.
4) ExtClassLoader tries to load the class. If the load is successful, the class object corresponding to the class is returned. If the load fails, the request is submitted to the appclassloader to try to load.
5) The appclassloader tries to load the class. If the load is successful, the class object corresponding to the class is returned. If the load fails, a classnotfoundException exception is thrown.
The role of the parental delegation mechanism
The main role of the parental delegation mechanism:
1) Prevent classes from being loaded repeatedly. In the JVM, each class is determined by a unique fully qualified name and a corresponding classloader, which determines the location of the class based on the fully qualified name and classpath. Therefore, if two classloaders load the same class in a JVM instance, the JVM will consider the two classes to be different classes, resulting in problems such as type conversion exceptions. Through the parental delegation mechanism, the classloader will delegate to its own parent classloader before loading the class, so as to ensure that only one copy of a class will be in the JVM and will be loaded by its parent classloader.
2) Prevent j**a core library classes from being tampered with and protect program security. For example, if you accidentally tamper with the J**A core library class (e.g., object class), due to the existence of the parental delegation mechanism, the tampered J**A core library class will not be loaded.
How to break the parental delegation mechanism
The logic of the parental delegation mechanism is implemented in the loadclass() method of the classloader class, and if you want to break the parental delegation mechanism, you need to override the loadclass() method of the classloader.
Tomcat breaks the parental delegation mechanism by customizing the classloader. As shown in Fig
The implementation principle of Tomcat can be consulted on the relevant information on the Internet, and the Tomcat series collection will be shared in the future.
Read Recommended] More exciting content, such as:
Redis series.
Data Structures & Algorithms.
NACOS series.
MySQL series.
JVM series.
Kafka series.
Please move to the personal homepage of [Nanqiu] for reference. The content is constantly being updated.
About the author] An old babe who loves technology and life, focuses on the field Xi of J**A, and pays attention to [Nanqiu] to take you to learn and grow together