当前位置:网站首页>This article takes you to understand the JVM class loading mechanism

This article takes you to understand the JVM class loading mechanism

2022-06-23 22:22:00 Great inventor

What is class loading

We wrote java Files are all stored with business logic code ,java Compiler will .java The file is compiled with an extension of .class The file of ,.class

There is... In the file java After the transformation , Instructions to be executed by the virtual machine ,

When a class is needed ,java Virtual opportunity loading .class file , And create the corresponding class object , take class The file is loaded into the memory of the virtual machine , This process is called class loading .

The final product of class loading is in the heap Class object ,Class Object encapsulates the data structure of class in method area , And to the Java The programmer provides an interface to access the data structure in the method area .

Class loader does not need to wait until a class is “ First active use of ” And then load it , JVM The specification allows a class loader to preload a class when it is expected to be used ;

If you encounter .class Missing or wrong file , The class loader must report an error the first time the program actively uses the class (LinkageError error ) If this class has not been actively used by the program , Then the classloader will not report errors .

Know what class to load , Now let's learn about JAVA The life cycle of a class

JAVA The life cycle of a class

JAVA The life cycle of a class

It can be seen that , JAVA The life cycle of a class is as follows :

  • load
  • verification
  • Get ready
  • analysis
  • initialization
  • Use
  • uninstall

Class loading includes loading 、 verification 、 Get ready 、 analysis 、 Initialize five stages .

PS:undefined verification 、 Get ready 、 These three parsing phases are also collectively referred to as the join phase

In these five stages , load 、 verification 、 The order in which these four phases occur is determined ;

The parsing phase is not necessarily , It can start after the initialization phase in some cases , This is to support Java Language runtime binding ( Also called dynamic binding or late binding ).

PS:undefined Also note that the stages here are sequential , Not in sequence or complete , Because these stages are usually mixed with each other , It usually calls or activates another stage in the execution of a phase .

load

The loading phase mainly finds and loads the binary data of the class , The class loader looks for such bytecode files by the fully qualified name of a class , And create a bytecode file class object .

In the loading phase , There are three things virtual machines need to do :

  1. Get the binary byte stream defined by the fully qualified name of a class
  2. Convert the static storage structure represented by the byte stream into the runtime data structure of the method area
  3. stay Java Generate a java.lang.Class object , As an access to the data in the method area

Relative to other stages of class loading , The loading phase is the most controllable phase , Because developers can use the classloader provided by the system to complete the loading , You can also use your own defined class loader to complete the loading .

JVM Class loader

Class loading is done by the class loader , Class loaders are usually made up of JVM Provide .

JVM These classloaders provided are often referred to as system classloaders ; besides , Developers can inherit ClassLoader Base class to create your own class loader .

JVM There are three predefined types of loaders :

  • Start class loader (Bootstrap ClassLoader)undefined Used to load Java The core of the class , It's implemented in native code , Not inherited from java.lang.ClassLoader( Responsible for loading $JAVA_HOME in jre/lib/rt.jar All in class, from C++ Realization , No ClassLoader Subclass );undefined Because the boot loader involves the details of the local implementation of the virtual machine , The developer can't get the reference of the boot loader directly , So it's not allowed to operate directly by reference
// Get the core class library loaded by the root class loader , And you will see that this machine is installed with Java Environment variable specified jdk The core of jar Package path 
public class ClassLoaderTest {
    public static void main(String[] args) {
        URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();
        for(URL url : urls){
            System.out.println(url.toExternalForm());
        }
    }
}

result

file:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/resources.jar
file:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/rt.jar
file:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/sunrsasign.jar
file:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/jsse.jar
file:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/jce.jar
file:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/charsets.jar
file:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/jfr.jar
file:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/classes
  • Extend the classloader (Extension ClassLoader)undefined It's responsible for loading JRE The extended directory for ,lib/ext Or by java.ext.dirs In the directory specified by the system property JAR Class of package , from Java Language implementation , The parent loader is null
  • Application class loader (Application ClassLoader)undefined It's called a system ( Also known as applications ) Class loader , It is responsible for the JVM Load at startup from Java Ordered - classpath Options 、java.class.path System attribute , perhaps CLASSPATH Change the specified variable JAR Package and classpath .undefined The program can go through ClassLoader Static method of getSystemClassLoader() To get the system classloader ; If not specified , Then the user-defined class loader takes this class loader as the parent loader , from Java Language implementation , The parent loader is ExtClassLoader.

Class loader loads Class The general process is as follows 8 A step :

  1. Check this Class Have you ever loaded , Whether there is this in the buffer Class, If there is a direct access to 8 Step , Otherwise enter the 2 Step
  2. If there is no parent loader , Then either Parent It's the root loader , Or it's the root class loader itself , Then jump to the 4 Step , If the parent loader exists , The first to 3 Step
  3. Request to use the parent loader to load the target class , If the load is successful, skip to 8 Step , Otherwise, proceed to section 5 Step
  4. Request to use the root class loader to load the target class , If the load is successful, skip to 8 Step , Otherwise, jump to the 7 Step
  5. The current classloader is trying to find Class file , If it is found, execute section 6 Step , If it can not be found, execute section 7 Step
  6. Load... From a file Class, After success, jump to the first 8 Step
  7. Throw out ClassNotFountException abnormal
  8. Return the corresponding java.lang.Class object
JVM Class loading mechanism

JVM The class loading mechanism of is as follows 3 Kind of :

  • Overall responsible for undefined The so-called overall responsibility , When a classloader is responsible for loading a certain Class when , The Class Relying on and quoting others Class This kind of loader will also be responsible for loading , Unless it is shown that another classloader is used to load
  • Caching mechanisms undefined The caching mechanism will ensure that all loaded Class Will be cached , When you need to use a Class when , Class loader first searches the cache for the Class, Only if it doesn't exist in the cache Class Object time , The system will read the binary data corresponding to this class , And turn it into Class object , In the buffer . That's why it's modified Class after , Must be restarted JVM, The reason why the program changes will take effect
  • Parents delegate undefined Parental delegation is when a classloader receives a request to load a class , It doesn't try to load the class itself first , Instead, the request is delegated to the parent loader to complete , If successful, it will directly return , Otherwise, keep going up , Until you reach the top class loader ;undefined therefore , All class loading requests should eventually be passed to the top-level boot class loader , Only if the parent loader cannot complete the load request , The child loader will try to load the class by itself

Parents delegate .png

JVM Load the class through the parent delegation model , Of course, we can also inherit java.lang.ClassLoader Implement custom class loader .

One of the benefits of using parental delegation is that for example, the load is located in rt.jar In bag java.lang.Object, No matter which loader loads this class , Finally, it is entrusted to the top-level boot class loader for loading , This ensures that different classloaders end up with the same Object object undefined In short :

The system class prevents multiple copies of the same bytecode from appearing in memory Guarantee Java Safe and stable operation of the program

JVM Class loading mode

JVM Yes 3 Type loading method :

  • The command line starts the application by JVM Initialize load
  • adopt ClassLoader.loadClass() Method to load dynamically undefined take .class File loading to jvm in , Not execute static The content in , Only in newInstance To execute static block ;undefinedClassloader.loaderClass Got class No connection yet ( verification 、 Get ready 、 analysis ) Of
  • adopt Class.forName() Method to load dynamically undefined Class like .class File loading to jvm in , It also explains the class , In the execution class static block ; Class.forName() Got class Is initialized

example :

package com.test.classloader;
public class loaderTest { 
        public static void main(String[] args) throws ClassNotFoundException { 
    ClassLoader loader = HelloWorld.class.getClassLoader(); 
    System.out.println(loader); 
    // Use ClassLoader.loadClass() To load a class , Initialization block... Will not be executed  
    loader.loadClass("TestClass"); 
    // Use Class.forName() To load a class , Initialization block is executed by default  
    Class.forName("TestClass"); 
    // Use Class.forName() To load a class , And designate ClassLoader, Static blocks are not executed during initialization  
    Class.forName("TestClass", false, loader); 
       } 
}
public class Test { 
        static { 
                System.out.println(" Static initialization block executed !"); 
        } 
}

verification

The verification phase is to ensure that Class The information contained in the byte stream of the file meets the requirements of the current virtual machine , And will not endanger the security of virtual machine itself .undefined The verification will be roughly completed 4 A test action :

File format validation undefined Verify that the byte stream matches Class Specification of document format .undefined for example : Whether or not to 0xCAFEBABE start ; Whether the primary and secondary version numbers are within the processing range of the current virtual machine ; Whether constants in constant pool have unsupported types ;

Metadata validation undefined Semantic analysis of information described by bytecode ( Be careful : contrast javac Semantic analysis in compilation phase ), In order to ensure that the information described in it conforms to Java The requirements of language norms ;

for example : Does this class have a parent class , except java.lang.Object outside ;

Bytecode verification undefined Through data flow and control flow analysis , Make sure the program semantics are legal 、 Logical .

Symbol reference validation undefined Make sure that the parsing action performs correctly .undefined The verification phase is very important , But it's not necessary , It has no effect on the running time of the program ;undefined If the referenced class is repeatedly verified , Then consider adopting -Xverifynone Parameter to close most class validation actions , To reduce the load time of virtual machine classes .

Get ready

The preparation stage is for static Modify class variables to allocate memory , And set the initial value of the class variable ;undefined All of this memory will be allocated in the method area ; It doesn't contain final Decorated static variables , because final Variables are allocated at compile time .

It should be noted that :

At this time, only class variables are included in memory allocation (static), Not instance variables ; Instance variables will be allocated along with a block of objects when they are instantiated Java In the pile . The initial value set here is usually the default zero value of the data type ( Such as 0、0L、null、false etc. ) Instead of being in Java The value in the code that is explicitly assigned .

for instance :undefined The variable... Is defined in the class public static int a =100;undefined Actually variable a The initial value after the preparation phase is 0 instead of 100;( Those who have doubts about this sentence can add JAVA Knowledge of data type initializers )undefined take a The assignment is 100 Of put static An instruction is when a program is compiled , Stored in class constructor <clinit>() Of the methods .

But pay attention to , If the statement is :public static final int a = 100;undefined During the compilation phase a Generate ConstantValue attribute , In the preparation stage, the virtual opportunity is based on ConstantValue Property will be a The assignment is 100

analysis

The parsing phase refers to that the virtual machine will Symbol reference Replace with Direct reference The process of ,undefined Mainly for classes or interfaces 、 Field 、 Class method 、 Interface method 、 Method type 、 Method handle and call point qualifier 7 Class symbol reference .undefined Symbol reference is a set of symbols to describe the target , It can be any literal amount .

Direct reference

A direct reference can be a pointer to a target , Relative offset or a handle that can be indirectly located to the target ; If there is a direct quote , The target of the reference must already exist in memory .

Symbol reference

Symbol references are independent of the layout of the virtual machine implementation , The target of the reference does not have to be loaded into memory .undefined The memory layout of various virtual machines can be different , But the symbolic references they can accept must be consistent ; Because the literal form of symbolic reference is clearly defined in Java Virtual machine specification Class In file format .

initialization

This is the last stage of class recording , If the class has a parent class, initialize the parent class , Execute its static initializer ( Static code block ) And statically initializing member variables .( The front is right static The default value is initialized , Here we assign a value to it , Member variables will also be initialized ).

JVM Responsible for class initialization , Class variables are mainly initialized .

Java There are two ways to set the initial value of class variables :

Declaring a class variable is specifying the initial value Use static code blocks to specify initial values for class variables

JVM Initialization steps

If this class has not been loaded and connected , Then the program first loads and connects the class If the direct parent of this class has not been initialized , First, initialize its immediate parent class If there are initialization statements in the class , Then the system executes these initialization statements in turn

Class initialization time

Only when the class is actively used will it lead to class initialization , Class includes the following six types of active use :

Create an instance of a class , That is to say new The way Accessing static variables of a class or interface , Or assign a value to the static variable Calling static methods of a class Reflection ( Such as Class.forName(“com.test.Test”)) Initializing a subclass of a class , The parent class will also be initialized Java The class marked as the startup class when the virtual machine starts (Java Test), Use it directly java.exe Command to run a main class

Note that the following situations do not perform class initialization :

Reference the static field of the parent class through the child class , Only the initialization of the parent class will be triggered , Does not trigger the initialization of the subclass Defining an array of objects , Initialization of this class will not be triggered Constants are stored in the constant pool of the calling class during compilation , Essentially, there is no direct reference to a class that defines a constant , The class in which the constant is defined will not be triggered Get by class name Class object , Class initialization will not be triggered adopt Class.forName When loading the specified class , If you specify parameters initialize by false when , Class initialization will not be triggered , In fact, this parameter tells the virtual machine , Do you want to initialize the class adopt ClassLoader default loadClass Method , It will not trigger the initialization action

原网站

版权声明
本文为[Great inventor]所创,转载请带上原文链接,感谢
https://yzsam.com/2021/12/202112151541452486.html