1.1 Class life cycle and loading process
The life cycle of a class in the JVM is divided into seven phases, 2. Loading, Verification, Preparation, Resolution, Initialization, Using, Unloading (1) must be an optimization of the Loading process. Steps 1 through 5 are collectively known as the class loading stage, and steps 2 through 4 are known as the linking stage.
1), load
- The main action in this phase is to read the class bytecode file in the file system, in the JAR package, or wherever it exists, and raise a NoClassDefFoundError if the binary class bytecode file is not found.
- The class bytecode file format is not verified during loading. The entire process of class loading is done jointly by the JVM and Java’s class loader system.
2), calibration
- The validation process is to ensure that the format of the class bytecode file (including checksums, version information, symbols in the constant pool, and type checking) is consistent with the current JVM. The process if the check is not legal may throw VerifyError, ClassFormatError, UnsupportedClassVersionError
- Validation is part of the linking phase, so the process loads all dependent classes, such as all parent classes and implemented interfaces. If there is a problem with the class hierarchy (for example, if a class is its own (indirect) parent, if an interface (indirect) extends itself or something similar), the JVM will throw a ClassCircularityError.
- And if the implementation of the interface is not an interface, or a statement of the superclass is an interface, also sell IncompatibleClassChangeError.
3), to prepare
- The preparation phase creates static fields and initializes them to default values (such as NULL or 0), and allocates the memory space used by these variables in the method area.
- No Java code is executed during the preparation phase.
4), parsing
- The parsing stage is the parsing symbol reference stage, that is, parsing constant pool, there are four main types: class or interface parsing, field parsing, class method parsing, interface method parsing.
- In Java source code, when a variable refers to an object, the reference is stored as a symbolic reference in the.class bytecode file, which acts as an index record.
- In the parsing phase, it needs to be parsed and linked as a direct reference, which is equivalent to pointing to the actual object. This process is also called dynamic linking. If there is a direct reference, then the target object of the reference must exist in the heap.
5) Initialization
- The JVM specification states that class initialization must be performed only when the class is first “actively used.”
- The initialization process includes executing: class constructor, static static variable assignment statement, static static code block.
- If a subclass is initialized, its parent class is initialized first.
1.2 Class loading timing
- When the VM starts, it initializes the main class specified by the user, which is the class where the main method is started.
- When the new directive creates an instance of a class, that is, an object of a new class;
- When an instruction that calls a static method is encountered, initialize the class of the static method;
- When an instruction is encountered that accesses a static field, initialize the class in which the static field resides.
- Initialization of a subclass triggers initialization of its parent class;
- If an interface defines the default method, the initialization of the class that implements the interface directly or indirectly triggers the initialization of the interface.
- When a reflection call is made to a class using the reflection API, it initializes the class. As before, the reflection call is either instantiated or static.
- The first time you call a MethodHandle instance, you initialize the class to which the method points.
1.3 Class initialization is not performed
- Accessing a static field of a parent class through a subclass only triggers initialization of the parent class, not the subclass.
- Defining an array of objects does not trigger initialization of the class.
- Constants are stored in the constant pool of the calling class at compile time. There is no direct reference to the class in which the constant is defined, and the class in which the constant is defined is not triggered.
- Getting a Class object by its name does not trigger Class initialization. Hello. Class does not initialize the Hello Class.
- If initialize is false, Class initialization is not triggered when a Class is loaded via class.forname. This parameter tells the vm whether to initialize the Class. Class.forname (” Jvm.hello “) loads the Hello Class by default.
- The default loadClass method of ClassLoader also does not trigger the initialization action (loaded, but not initialized).
1.4 Class loader mechanism
Class loaders of the system are divided into three types:
- Start the class loader (BootstrapClassLoader)
- Extended class loader (ExtClassLoader)
- Application Classloader
The startup ClassLoader is typically implemented within the JVM, written in C++, does not inherit from java.lang.ClassLoader and is not available in the Java API, but we can see and influence it from the side. The last two types of loaders are defined in the Oracle Hotspot JVM in sun.misc.Launcher. The extension classloader and application classloader generally inherit from the URLClassLoader class. This class also implements methods to convert class bytecode from various sources by default.
1.4.1 Starting the ClassLoader (BootstrapClassLoader)
Java.lang.ClassLoader is not inherited from java.lang.ClassLoader. It is responsible for loading all the classes in the JDK jre/lib/rt.jar. We can’t directly get a reference to the start class loader at the code level, so we’re not allowed to manipulate it directly. Such as Java. Lang. The String is made up of start the class loader loaded,. So the String class. GetClassLoader () will return null.
1.4.2 ExtClassLoader:
ExtClassLoader, loaded by BootstrapClassLoader, is an internal class defined in sun.misc.Launcher that loads the extension directory of the JRE, A class in a jar package in lib/ext or in a directory specified by the java.ext.dirs system argument has a null parent class loader because it cannot get the boot class loader.
1.4.3 AppClassLoader:
AppClassLoader is loaded by ExtClassLoader and is an internal class defined in sun.misc.Launcher. It is responsible for loading the -classpath or -cp option from the Java command, the JAR packages specified by the java.class.path system parameter, and the classpath at JVM startup. If not specified, user-defined classes are loaded from the custom class loader if no custom class loader is used.
1.4.4 Class hierarchy of class loaders
1.4.5 Customizing class loaders
If a user defines a custom class loader, the custom class loader takes the AppClassLoader as the parent loader. You can inherit a custom ClassLoader directly from a ClassLoader, or you can inherit a SecureClassLoader or URLClassLoader to implement a custom ClassLoader. Inheriting SecureClassLoader preserves the checking logic for security policies.
1.4.6 Characteristics of class loading mechanism
1) Parental delegation mechanism
When a class loader (except BootstrapClassLoader) loads a class, it delegates the class to its parent class loader. If the parent class loader finds that it still has a parent class loader, it delegates to the top class loader, all the way to the topmost class loader. As long as the top of the class loader to load the class will be finished loading process, if there is no loaded into the top class loader class, will be cascaded down Let subclasses of loader attempts to load at all levels, as long as the level in a certain class loader loads to complete the loading process, if all class loaders are not loaded into the class, ClassNotFountException is thrown
The way to break parental delegation is to override both the findClass and loadClass methods of the ClassLoader.
2) Responsible for dependency
If a class loader loads a class and finds that the class depends on several other classes or interfaces, it will try to load those dependent classes as well.
3) Cache loading
To improve loading efficiency and eliminate double loading, once a class is loaded by a class loader, it caches the load result and does not load again.