load
When we want to use a class, we need to load the class into memory through ClassLoader
The class loading phase mainly completes the following three things
- Get the binary stream of the class by the full class name
- Parse the binary stream of the class into a data structure within the method area
- Create an instance of the java.lang.Class class, representing the type, as the access entry for this class in the method area
There are many ways to get the binary stream of a class through the full class name
- Get it from the zip archive
- get from the web
- Runtime computation generation, such as dynamic proxy techniques
- …
For the loading phase of non-array types, you can use the built-in class loader of the Java virtual machine to complete it, or you can use a user-defined class loader to complete it.
Link
This stage of linking is mainly divided into 3 parts, verification, preparation, and analysis
verify
The verification phase is mainly to ensure that the format of the Class file is correct, and the security of the virtual machine will not be compromised when running.
There are many rules in the verification stage, but they are roughly divided into the following four stages
. I will not explain them in detail. You can read "In-depth Understanding of Java Virtual Machine". This article tends to make a summary and grasp one of class loading. The overall process without elaborating on the details
Prepare
The preparation phase is mainly to allocate memory for the static variables of the class and initialize them to default values
The default values for common data types are as follows
type of data | Defaults |
---|---|
byte | (byte)0 |
short | (short)0 |
int | 0 |
long | 0L |
float | 0.0f |
double | 0.0d |
boolean | false |
char | ‘\u0000’ |
reference | null |
If the ConstantValue attribute exists in the field attribute table of the class static variable, the assignment statement is executed directly
So under what circumstances does the ConstantValue attribute exist in the field attribute table of the class static variable?
- Class static variables are basic data types and are modified by final
- Class static variables are of type String, modified by final, and assigned in the form of literals
In order to easily view the bytecode of the Class file, I downloaded a plug-in jclasslib Bytecode viewer in IDEA, which is very convenient. Use the following code to verify it in the form of bytecode
public class Person {
private static int age = 10;
private static final int length = 160;
private static final String name = "name";
private static final String loc = new String("loc");
}
So the length and name properties will be assigned the value specified by ConstantValue in the preparation stage
So at what stage are the age and loc properties assigned? It is in the initialization phase, which will be described in detail later.
Parse
Converts symbolic references (in the constant pool) of classes, interfaces, fields, and methods to direct
references
To add I wrote a class like the following
public class Student {
private String name;
private int age;
public String getName() {
return this.name;
}
}
Taking fields as an example, the objects corresponding to name and age do not directly point to memory addresses, but are described by strings (that is, symbolic references). The parsing phase is to convert these descriptions into pointers directly to the target (ie, direct references)
initialization
Execute class static member variable assignment statements and statements in static code blocks
We change the above Student code to the following form
public class Student {
private String name;
private int age = 10;
private static int gender = 1;
{
System.out.println("构造代码块");
}
static {
System.out.println("静态代码块");
}
public Student() {
System.out.println("构造函数");
}
public String getName() {
return this.name;
}
}
You can see that the bytecode contains 3 methods. We know the getName method. What logic is executed in the <init> and <clinit> methods?
Analysis of a wave from the perspective of bytecode
<init> method
From the bytecode, we can see that the main logic of the <init> method is
- Call the <init> method of the parent class
- non-static member variable assignment
- execute block of code
- execute the constructor
<clinit> method
From the bytecode, we can see that the main logic of the <clinit> method is
- Execute assignment statement for static variable
- Execute a statement in a static code block
- It should be noted that the Java virtual machine ensures that the <client> method of the parent class has been executed before the <client> method of the subclass is executed.
It is necessary to understand the role of <clinit> and <init> methods, because there are often interview questions about static code blocks, construction code blocks, and the execution order of constructors.
I will directly summarize the conclusion here. You can write a demo to verify it.
Execution order without inheritance
- Static code blocks and static member variables, the execution order is determined by the writing order (only executed once)
- Construct code blocks and non-static member variables, the order of execution is determined by the order of writing
- Constructor
Execution order with inheritance
- The static of the parent class (static code block, static member variable), the static of the subclass (static code block, static member variable) (only executed once)
- The non-static (construction code block, non-static member variable) of the parent class, the constructor of the parent class
- Subclass's non-static (construction code block, non-static member variable), subclass's constructor
uninstall
Garbage collection happens not only on the heap, but also on the method area. However, the conditions for recycling the type data in the method area are relatively harsh
. The following figure is an example. I want to recycle the Simple class in the method area.
- Need to ensure that the Sample class and its subclasses in the heap have been recycled
- The MyClassLoader that loads the Sample class has been recycled
- The Class object corresponding to the Sample class has been recycled
It can be seen that the conditions for reclaiming the type data in the method area are harsh, but the effect is very small, so some garbage collectors will not reclaim the type data in the method area.
Summarize
class loading process
variable assignment process
Reference blog
[1] https://www.cnblogs.com/caoxb/p/12735525.html
[2] https://m.xp.cn/b.php/103736.html
Good article
[3] https://ricstudio.
Execution timing of top/archives/classloadmechanism <init> and <client> methods
[4]https://www.zhihu.com/question/447387629/answer/1762489678