JVM combat: class loading process

Please add image description

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

  1. Get the binary stream of the class by the full class name
  2. Parse the binary stream of the class into a data structure within the method area
  3. Create an instance of the java.lang.Class class, representing the type, as the access entry for this class in the method area

Please add image description

There are many ways to get the binary stream of a class through the full class name

  1. Get it from the zip archive
  2. get from the web
  3. 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
insert image description here
. 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?

  1. Class static variables are basic data types and are modified by final
  2. 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");
}

insert image description here
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.
insert image description here

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;
    }
}

insert image description hereTaking 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

insert image description here

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?
insert image description here
Analysis of a wave from the perspective of bytecode

<init> method

insert image description here

From the bytecode, we can see that the main logic of the <init> method is

  1. Call the <init> method of the parent class
  2. non-static member variable assignment
  3. execute block of code
  4. execute the constructor

insert image description here
<clinit> method
insert image description here
From the bytecode, we can see that the main logic of the <clinit> method is

  1. Execute assignment statement for static variable
  2. Execute a statement in a static code block
  3. 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

  1. Static code blocks and static member variables, the execution order is determined by the writing order (only executed once)
  2. Construct code blocks and non-static member variables, the order of execution is determined by the order of writing
  3. Constructor

Execution order with inheritance

  1. 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)
  2. The non-static (construction code block, non-static member variable) of the parent class, the constructor of the parent class
  3. 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
insert image description here
insert image description here
. The following figure is an example. I want to recycle the Simple class in the method area.

  1. Need to ensure that the Sample class and its subclasses in the heap have been recycled
  2. The MyClassLoader that loads the Sample class has been recycled
  3. The Class object corresponding to the Sample class has been recycled
    insert image description here

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
Please add image description

variable assignment process
Please add image description

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

Guess you like

Origin blog.csdn.net/zzti_erlie/article/details/123383833