We learned about the structure of the Class file, and all kinds of information described in the Class file must be loaded into the VIRTUAL machine before it can be run and used.

Next, we’ll start learning about class loading for the JVM.

There are seven stages in the life cycle of a class, from being loaded into virtual machine memory to being unloaded from memory: Loading, Verification, Preparation, Resolution, Initialization, Using and Unloading, The three parts of validation, preparation and parsing are collectively referred to as Linking.

The Java Virtual Machine Specification specifies that there are only six cases in which classes must be “initialized” immediately:

  • 1) When the bytecode instructions new, getstatic, putstatic, or Invokestatic are encountered, if the type has not been initialized, the initialization phase needs to be triggered first.
  • 2) When a reflection call is made to a type using a java.lang.reflect method, if the type has not already been initialized, it needs to be initialized first.
  • 3) When initializing a class, if the parent class has not been initialized, the initialization of the parent class needs to be triggered first.
  • 4) When the virtual machine starts, the user needs to specify a primary class (the one containing the main() method) to execute, and the virtual machine initializes this primary class first.
  • 5) When using the new dynamic language support in JDK 7, If a Java lang. Invoke. The final analytical results for MethodHandle instance REF_getStatic, REF_putStatic, REF_invokeStatic, REF_newInvokeSpecial handle four kinds of methods, If the class corresponding to the method handle has not been initialized, it needs to be initialized first.
  • 6) When an interface defines a new JDK 8 default method (an interface method modified by the default keyword), if any of the interface’s implementation classes are initialized, the interface should be initialized before it.

The behavior in these six scenarios is called making active references to a type.

Let’s take a closer look at the entire process of class loading in a Java virtual machine, namely loading, validating, preparing, parsing, and initializing.

1, load,

Loading is the starting point of JVM loading. The Java Virtual Machine Specification does not enforce any restrictions on when to start loading. The implementation can be left to the virtual machine.

During the loading process, the JVM does three things:

  • 1) Get the binary byte stream that defines a class by its fully qualified name.

  • 2) Convert the static storage structure represented by this byte stream to the runtime data structure of the method area.

  • 3) Generate a java.lang.Class object representing the Class in memory as an access point to the various data of the Class in the method area.

After the loading phase is complete, the external binary byte streams of the Java VM are stored in the method area in the format set by the VM. The data storage format in the method area is fully defined by the VM. The Java Virtual Machine Specification does not specify the specific data structure in this area.

Once the type data is properly placed in the method area, an object of the Java.lang. Class Class is instantiated in the Java heap memory, which acts as an external interface for the program to access the type data in the method area.

The specific implementation of method sections in different JDK versions is not covered in detail. In JDK1.8, type data is stored in a meta-space.

2, validation,

Validation is the first step in the connection phase, which aims to ensure that the information contained in the byte stream of a Class file complies with all the constraints of the Java Virtual Machine Specification.

The verification phase will roughly complete the following four stages of verification: file format verification, metadata verification, bytecode verification and symbol reference verification.

  • File format validation

The first step is to verify that the byte stream complies with the Class file format specification and can be processed by the current version of the VIRTUAL machine. You need to verify magic numbers, version numbers, whether constant pool constant types are supported, index values pointing to constants, and so on.

  • Metadata validation

The second stage is semantic analysis of the information described by bytecode to ensure that the information described conforms to the requirements of the Java Language Specification, including whether the class has a parent class, whether the parent class inherits the final modified class, whether the non-abstract class implements the methods defined by the parent class, whether the class has conflicts with the parent class, and so on.

  • Bytecode verification

The third stage is the most complicated one in the whole validation process. The main purpose is to determine the program semantics is legal and logical through data flow analysis and control flow analysis.

  • Symbolic reference verification

The validation behavior in the last phase occurs when the virtual machine converts symbolic references to direct references, which occurs in the parse phase, the third phase of the connection.

Symbolic reference validation mainly verifies that a class is missing or denied access to some external class, method, field, and other resources on which it depends.

3, preparation,

The preparation phase allocates memory for static variables and sets initial values for class variables.

In JDK 7 and before, the memory of these variables was allocated in the method area (permanent generation), and in JDK 8 and after, static variables were stored in the Java heap along with Class objects.

4, parsing,

The parsing phase is the process by which the Java virtual machine replaces symbolic references in the constant pool with direct references.

  • Symbolic References: Symbolic References describe the referenced target as a set of symbols, which can be any literal, as long as they are used to unambiguously locate the target.
  • Direct References: A Direct reference is a pointer that can point directly to the target, a relative offset, or a handle that can be indirectly located to the target.

5. Initialization

The initialization phase of a class is the final step in the class loading process, where class variables and other resources are initialized according to a programmer’s subjective plan made through program coding.

In the preparation phase, variables are assigned the zero value required by the system. In the initialization phase, variables are assigned the value written in the code.

Now that you’ve covered the basics of the classloading process, we’ll look at the classloader responsible for completing the loading phase.