Memory and garbage collection of JVM learning 1

1 JVM and Java Architecture

1.0 Java Development Major Events

In 2000, JDK 1.3 was released, and the Java Hot Spot Virtual Machine was officially released, becoming the default virtual machine for Java.
In 2006, JDK 6 was released. In the same year, Java was open-sourced and OpenJDK was established. Naturally, the Hotspot virtual machine has also become the default virtual machine in OpenJDK.
In 2008, Oracle acquired BEA and got the JRockit virtual machine.
In 2010, Oracle acquired Sun, acquiring the Java trademark and the HotSpot virtual machine.
In 2011, the G1 garbage collector was officially enabled in JDK 7.
In 2017, G1 became the default GC in JDK 9, replacing CMS. IBM also open sourced the J9 virtual machine.
In 2018, the JDK 11 LTS version released the revolutionary ZGC and adjusted the jdk license.
In 2019, JDK 12 was released, adding Shenandoah gc.

1.1 Virtual machine and Java virtual machine

A virtual machine is a virtual computer, which is software used to execute a series of virtual computer instructions. It can be roughly divided into system virtual machines and program virtual machines.

Visual Box and VMWare are system virtual machines. They are completely emulations of physical computers and provide a complete operating system software platform that can run. The Java virtual machine is a typical program virtual machine, which is specially designed to execute a single computer program.

No matter what kind of virtual machine it is, the software running on it is limited to the resources provided by the virtual machine.

A Java virtual machine is a virtual computer that executes bytecode (this bytecode can be generated by the Java language or by other languages).

insert image description here

1.3 JVM overall structure

insert image description here

1.4 Java code execution process

Java source code (xxx.java)
compilation (front-end compilation): lexical analysis, syntax analysis, grammar/abstract syntax tree, semantic analysis, annotation abstract syntax tree and bytecode generator.
Bytecode (xxx.class)
Java virtual machine: class loader, bytecode verifier, bytecode interpreter and JIT compiler
binary instructions
operating system

1.5 JVM architecture model

The instruction stream input by the Java compiler is basically a stack-based instruction set architecture , and another instruction architecture is a register-based instruction architecture .
Stack architecture features:

  1. Easier to design and implement, suitable for resource-constrained systems.
  2. Avoid the problem of register allocation: use zero address instruction to allocate.
  3. Most of the instructions in the instruction stream are zero-address instructions, and their execution depends on the operation stack. The instruction set is smaller ( single instruction is shorter ), and the compiler is easy to implement.
  4. No need for hardware support, better portability, and better cross-platform implementation.

Features of register architecture:
5. Typical applications are x86 binary instruction set: traditional pc and Android's Davlik virtual machine.
6. The instruction set architecture is completely dependent on hardware and has poor portability.
7. Excellent performance and efficient execution.
8. It takes fewer instructions (fewer instructions) to complete an operation.
9. In most cases, the instruction set based on the register architecture tends to be dominated by one-address instructions, two-address instructions and three-address instructions. Stack-based instruction architectures are often dominated by zero-address instructions.

Example: Realize 2+3 under two instruction architectures

iconst_2  // 常量2入栈
istore_1
iconst_3 // 常量3入栈
istore_2
iload_1
iload_2
iadd // 常量2,3出栈,执行相加
istore_0  // 结果5入栈
mov eax,2 // eax 初始值设置为2
add eax,3 // 将寄存器内的值+3

1.6 JVM life cycle

[Startup]
The startup of the Java virtual machine is done by creating an initial class (initial class) through the bootstrap class loader, which is specified by the specific implementation of the virtual machine.
[Execution]
A running Java virtual machine has a clear task: to execute java programs.
It runs when the program starts executing and stops when the program ends.
When executing a Java program, what is actually executed is the process of a Java virtual machine.
【quit】

  • The program ends normally
  • The program encounters an exception or error during execution and terminates abnormally
  • The Java virtual machine process terminated due to an error in the operating system.
  • A thread calls the exit method of the Runtime class or the System class, or calls the halt method of the Runtime class, and the Java security manager also allows this exit or halt operation.
  • The JNI specification describes that when the JNI Invocation API is used to load or unload the Java virtual machine, the Java virtual machine exits.

1.7 JVM development history

[Sun Classic VM]
In 1996, JDK1.0 released the first commercial java virtual machine, Sun Classic VM. It was eliminated in jdk 1.4.
This VM only provides an interpreter .
If you want to use the jit compiler, you need to plug it in. Once the JIT is used, the JIT takes over the execution system of the virtual machine. The interpreter just doesn't work anymore. Interpreters and compilers don't work together.
This virtual machine is now built into the HotSpot virtual machine.

【Exact VM】

  • This virtual machine is provided when jdk1.2 is used.
  • Exact Memory Management: Accurate memory management. The virtual machine can know what type of data is in a certain location in memory.
  • It has the prototype of a modern high-performance virtual machine: (1) hotspot detection (2) mixed working mode of compiler and interpreter.
  • Used only briefly on the Solaris platform. Eventually replaced by Hotspot.

【HotSpot VM】

  • jdk1.3 became the default virtual machine.
  • Occupy an absolute market position and dominate the martial arts world. Both Oracle jdk and OpenJDK are the default virtual machines.
  • Use hot spot detection technology. Find the code with the most compilation value through the counter, trigger just-in-time compilation or replacement on the stack. The compiler and interpreter work together to strike a balance between optimal response time and best execution performance.

【JRockit VM】

  • Focus on server-side applications. It does not pay attention to the startup speed, does not contain an interpreter inside, and all codes are compiled and executed by a just-in-time compiler.
  • Fastest JVM

【J9】

  • IBM Corporation
  • Known as the fastest virtual machine. Mainly because it works better on IBM products.

【VM Blue】

  • A dedicated virtual machine that is bound to a specific hardware platform and works with software and hardware.
  • Each Azul VM instance can manage hardware resources of at least dozens of CPUs and hundreds of GB of memory, and provides excellent features such as a garbage collector that realizes controllable GC time within a huge memory range, and thread scheduling optimized by proprietary hardware.

【Liquid VM】

  • A dedicated virtual machine that is bound to a specific hardware platform and works with software and hardware.
  • Liquid VM does not require the support of the operating system, or it itself implements the necessary functions of a dedicated operating system, such as thread scheduling, file system and network support.

【Apache Harmony】

  • Its Java class library code is absorbed into the Android SDK.

【Micorsoft JVM】

  • The original intention was to support Java Applets in the IE browser, and it could only run on the Windows platform. It was the Java VM with the best performance under the Windows platform at that time.
  • In 1997, this VM was taken off the shelves due to trademark infringement, unfair competition and other crimes.

【TaobaoJVM】

  • Ali developed its own customized AlibabaJDK based on OpenJDK
  • It is a highly customized and open source high-performance server version of the Java virtual machine.
  • GCIH (GC Invisible heap) technology realizes off-heap, that is, Java objects with a long life cycle are moved from the heap to outside the heap, and the GC cannot manage the Java objects inside the GCIH, so as to reduce the frequency of GC recycling and improve the recycling efficiency of GC.
  • Objects in GCIH can be shared among multiple virtual machine processes.
  • Relying heavily on intel's cpu, it loses compatibility and improves performance.

【Dalvik VM】

  • Developed by Goolge, applied to Android system, and provided JIT in Android2.2
  • Dalvik VM can only be called a virtual machine, not a "Java virtual machine". It does not follow the Java virtual machine specification.
  • The dex (Dalvik Executable) file is executed, which is more efficient. The dex file can be converted from the classes file.
  • Register-Based Instruction Architecture
  • Android 5.0 replaces the Dalvik VM with the ART VM that supports Ahead of Time Compilation (AOT).

【Grail VM】

  • 2018.04 Oracle Labs public
  • Run Programmes Faster Anywhere
  • A cross-language full-stack virtual machine that can be used as a running platform for "any language". Including c and cpp.

2 class loading subsystem

2.1 ClassLoader

insert image description here
There can be multiple ClassLoaders.

The specific file identifier in the file header is "coffee baby".
insert image description here
insert image description here
All class loaders are not an inheritance relationship, but can be regarded as a hierarchical relationship. The highest-level bootstrap will always load objects first, and those that cannot be loaded will be the turn later.

[Bootstrap class loader]
The bootstrap loader loads jre/lib/rt.jar, resources.jaror sun.boot.class.paththe content in the path, Object class, String class, ArrayList, etc. are all loaded by it.
View the loading path of the startup class loader

URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();

Load extension classes and application class loaders, and specify them as their parent class loaders.
For security reasons, the Bootstrap startup class loader only loads classes whose package names start with java, javax, sun, etc.

[Ext class loader]
The extension class loader loads the content in jre/lib/ext/*.jar.
If the jar package created by the user is also placed in the ext directory, it will also be automatically loaded by the ext class loader.

View the loading path of the extension class loader

String extDirs = System.getProperty("java.ext.dirs");
String dirArr = extDirs.split(";");

[System Class Loader]
The application class loader loads custom objects in Java code.
Responsible for loading the class library under the path specified by the environment variable classpath or the system property java.class.path.
The system class loader is the default class loader in the program. Generally speaking, the classes of Java applications are completed by it.
Such loaders can be obtained as follows:ClassLoader.getSystemClassLoader()

Verification use case program

package org.example.classloader;

import com.sun.nio.zipfs.JarFileSystemProvider;

public class ClassLoaderTest {
    
    
    public static void main(String[] args) {
    
    
        Object o = new Object();
        System.out.println(o.getClass().getClassLoader()); // bootstrap class loader 获得不到的,返回值为null

        System.out.println("==========================================");

        MyObject myObject = new MyObject();
        System.out.println(myObject.getClass().getClassLoader());
        System.out.println(myObject.getClass().getClassLoader().getParent());
        System.out.println(myObject.getClass().getClassLoader().getParent().getParent());

        System.out.println("==========================================");

        JarFileSystemProvider provider = new JarFileSystemProvider();
        System.out.println(provider.getClass().getClassLoader());
        System.out.println(provider.getClass().getClassLoader().getParent());
    }
}

class MyObject {
    
    

}


null
==========================================
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@14ae5a5
null
==========================================
sun.misc.Launcher$ExtClassLoader@14ae5a5
null

From the perspective of JVM specification, there are two types of class loaders: Bootstrap ClassLoader and User-defined ClassLoader. In the Java virtual machine specification, all class loaders derived from ClassLoader are classified as custom class loaders.

The way to get classLoader:

  1. Get the ClassLoader of a class
clazz.getClassLoader();
  1. Get the ClassLoader of the current thread context
Thread.currentThread().getContextClassLoader();
  1. Get the ClassLoader of the system
ClassLoader.getSystemClassLoader();
  1. Get the caller's ClassLoader
DriverManger.getCallerClassLoader();

2.2 User-defined class loader

2.2.1 Why do you need a custom class loader

  • Isolated class loader
  • Modify the class loading method
  • Extended load source
  • Prevent source code leakage

2.2.2 Implementation steps of custom class loader

  1. Inheriting abstract classes java.lang.ClassLoader, it is recommended to put custom class loading logic findClass()in methods.
  2. If there are no particularly complex requirements, you can directly inherit URLClassLoader, which can avoid writing the findClass method and the way to obtain the bytecode stream yourself, and make writing a custom class loader more concise.

2.3 Parental delegation mechanism

insert image description here
Mnemonic: "poke up"

A case is used to prove that the parental delegation mechanism ensures the security of Java code.

package java.lang;

public class String {
    
    
    public static void main(String[] args) {
    
    
        System.out.println("Hello World");
    }
}


错误: 在类 java.lang.String 中找不到 main 方法, 请将 main 方法定义为:
   public static void main(String[] args)
否则 JavaFX 应用程序类必须扩展javafx.application.Application

The benefits of the parental delegation mechanism:

  • Avoid duplicate loading of classes
  • Protect the security of the program and prevent the core API from being tampered with at will.

2.3 Class loading process

Loading -> [Verification -> Preparation -> Resolution] -> Initialization
--------------------------【This is the linking process】

【load】

  1. Get the binary byte stream defining this class by its fully qualified name
  2. Convert the static storage structure defined by this byte stream into the runtime data structure of the method area
  3. A java.lang.Class object representing this class is generated in memory as the access entry for various data of this class in the method area.

The source of the .class file:

  • in the local system
  • Network acquisition, typical scenario: Web Applet.
  • Reading from zip package is the basis of reading from jar and war.
  • Runtime calculation generation, the most used is the dynamic proxy technology.
  • Generated by other files, typical scenario: jsp application
  • Extract .class files from a proprietary database, relatively rare
  • Obtained from encrypted files, a typical protection measure to prevent Class files from being decompiled.

【verify】

  1. The purpose is to ensure that the information contained in the class file meets the requirements of the current virtual machine, to ensure the correctness of the loaded classes, and not to endanger the safety of the virtual machine itself.
  2. It mainly includes four types of verification: file format verification, metadata verification, bytecode verification, and symbol reference verification.

【Prepare】

  1. Allocate memory for class variables and set the default initial value of class variables, ie zero value
  2. If it is a static variable modified by final, it is already a constant. The constant has been assigned a value in the compilation phase, and the initialization will be displayed in the preparation phase.
  3. Here, instance variables will not be allocated for initialization, class variables will be allocated in the method area, and instance variables will be allocated to the Java heap along with the object.

【Analysis】

  1. The process of converting symbols used in the constant pool into direct references.
  2. In fact, parsing operations are often accompanied by JVM execution after initialization.

[Initialization]
4. The initialization phase is the process of executing the class constructor method <clinit>() . <clinit>()It is different from the class constructor (association: the constructor is from the perspective of the virtual machine <init>())
5. <clinit>()It does not need to be defined. It is a combination of the assignment actions of all class variables in the class automatically collected by the javac compiler and the statements in the static code block. Instructions in a class constructor method are executed in the order in which the statements appear in the source file. 6. If a class has a parent class, the JVM will ensure that the method of the parent class has been executed before the execution
of the subclass . 7. The virtual machine must ensure that a method of a class is locked synchronously in a multi-threaded environment. 8.<clinit>()<clinit>()
<clinit>()

public class ClassInitTest {
    
    
	static {
    
    
		number = 20;
		// 报错:非法的前向引用
		// System.out.println(number);
	}

	// prepare : number = 0;
	// initial : 20 ---> 10
	private static int number = 10; 

	public static void main(String[] args) {
    
    
		System.out.println(ClassInitTest.number); // 10
	}
}

2.4 Others

In the JVM, there are two necessary conditions to indicate whether two class objects are of the same class:

  • The full class name of the class must be consistent, including the package name
  • The ClassLoader (referring to the ClassLoader instance object) that loads this class must be the same

The JVM must know whether a type was loaded by the startup class loader or by the user class loader. If a type is loaded by a user class loader, the JVM will save a reference to the class loader as part of the type information in the method area. When resolving a reference from one type to another, the JVM needs to ensure that the class loaders for both types are the same.

The use of classes by Java programs is divided into: active use and passive use.
Active usage:
1 Create an instance of a class 2 Access a static variable of a class or interface , or assign a value
to the static variable 3 Call a
static method of a class 4
Reflection (such as Class. initialization .


java.lang.invoke.MethodHandleREF_getStatciREF-putStaticREF-invokeStatic

References

[1] https://www.bilibili.com/video/BV1jJ411t71s?p=5&spm_id_from=pageDriver&vd_source=f4dcb991bbc4da0932ef216329aefb60

Guess you like

Origin blog.csdn.net/kaikai_sk/article/details/131592026