The introduction
As we all know, The Slogan of Java is “Write once, Run anywhere.”, which means that no matter what platform we use Java to implement on the machine, it can run directly on any System that supports Java without any additional operations. How does Java do this? The answer is JRE.
- So what is JRE? Why is it called JRE?
- The Java Runtime Environment (JRE) is a Runtime Environment for Java code. It runs on the operating system software and is part of the JDK.
- What is the JDK?
- Java Development Kit (JDK), each JDK contains a compatible JRE and a JVM, and the JDK contains many tools and class libraries commonly used by Java developers, such as
javac
,java
,jar
,jmap
,jstat
,jstack
,jinfo
,rt.jar
And so on.- What is the JVM?
- JVM(Java Virtual Machine),JVM can be understood as a Virtual computer running on the operating system, when we pass
javac
will*.java
Compile to be recognized by the JVM*.class
After the bytecode file is executedjava
, at which point the JVM will*.class
Bytecode files are interpreted to be executed in machine code that is recognized by the current operating system platform. In this way, “Write once, run anywhere.”- The overall process is as follows
The process of JVM class loading
Loading stage:
- Read a binary stream of class bytecode files by the fully qualified name of the class
- Convert static data structures in the byte stream to runtime data structures in the method area
- Generate an in-memory representation of this class
java.lang.Class
Object as an access point to the various data structures in this class in the method area
- Note:
- This is just one phase of class loading, not to be confused with class loading
- Some of the actions in the load phase and the link phase intersect, and the link phase may have started before the load phase is complete
Linking stage
- validation
- File format verification: Ensures that the byte stream of a class file contains information that complies with vm specifications and does not compromise vm security
- Metadata validation: Semantic analysis
- Whether there is a parent class (divided by
java.lang.Object
All classes must have a parent class. - Whether classes are inherited that shouldn’t be
- If it is not an abstract class, whether all methods required in the parent class or interface are implemented
- Whether a field or method conflicts with a parent class
- Whether there is a parent class (divided by
- Bytecode verification:
- Make sure the semantics are legal and logical
- Class methods do not do events that harm the virtual machine
- Symbolic reference validation: Occurs when converting symbolic references to direct references -> parses
- Whether a class can be found for a fully qualified name
- Specifies whether referenced methods and fields exist in the class
- Whether the accessibility of classes, fields, methods in symbolic references can be accessed by the current class (private, protected, public, default)
- Preparation:
- Memory is allocated in the method area for class variables (modified static) and instance variables are allocated in the Java heap when the object is instantiated
- Set the initial value, at which point zero is assigned, and the real value is assigned at initialization. Finnal exception, direct assignment;
Public static int value = 99; Public static final int value = 99; Public static int value = 0; Public static final int value = 99;Copy the code
- Resolution: Replace symbolic references in the constant pool with direct references
- Class or interface resolution
- Field analytical
- Class method resolution
- Interface method parsing
Initialize the
- This is the last step in the class loading process, and the virtual machine dominates and controls all phases except the loading phase, during which the user can participate through a custom class loader
- This is where the actual initialization of the Java program code (or bytecode) defined in the class begins, calling
<clinit>()
Initialization is triggered when:
- When the VM starts, initialize the main class specified by the user.
- Initialize the target class of the new instruction when it encounters a new instruction for creating an instance of the target 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.
- Initialize a class when a reflection call is made to the class using the reflection API;
- The first time you call a MethodHandle instance, you initialize the class to which the method points.
At this point, a bytecode file is initialized.
This paper summarizes
The loading process of a class is generally divided into three steps: loading, linking, and initialization. The linking stage is divided into three stages: verification, preparation, and parsing. The loading stage reads the binary stream of the class bytecode file through the fully qualified name of the class and converts the bytecode data into the runtime data structure of the method area. The validation phase in the linking phase verifies the format and security of the bytecode file, the preparation phase allocates memory and assignment of initial values for some variables in the class (variables modified by static), and the parsing phase replaces symbolic references in the constant pool with direct references. In the initialization phase, assignment operations of static code and code in static code blocks are handed over to the < Clinit >() method for initialization, completing variable assignment and resource allocation.
Issues related to
How does the virtual machine find the corresponding Class file by the fully qualified name of the Class?
- JVM class loaders with parental delegation model