Definition of virtual machine: a software-simulated computer system with complete hardware functionality that runs in a separate, isolated environment

JVM A Java VIRTUAL machine (JVM), which simulates Java bytecode instructions through software, is the running environment for Java programs

Overview of the class loading process

Compile (javac.exe) —- load —– Interpreter (java.exe) —— Memory allocation, bytecode execution, garbage collection, efficient concurrent processing

The loading process is platform-independent, and the compiled.class files are interpreted and executed by different VMS

Class file structure

Magic number, version number, major version number, constant pool, access flag (class or interface, public or final or abstract, etc.)

Constant pool includes two categories, literal and symbolic references to the Java equivalent of literal constants, such as text string that is declared final constant values, symbols, including reference is module import or open the package, class of the interface and the fully qualified name, the name of the field and descriptors, the name of the method and the descriptor, method handle and type, Dynamic call points and dynamic constants.

The class file does not hold information about the final in-memory layout of methods and fields. Symbolic references to these fields and methods cannot be translated to the final in-memory address entry without the virtual machine converting them at runtime

Javap -verbose *. Class //verbose

public class TestClass { private int m=5; public int test(){ return m+1; }}Copy the code
$ javap -verbose TestClass.class Classfile /D:/background-start/background-starter/src/main/java/com/mxx/starter/test/TestClass.class Last modified 2020-12-30; size 306 bytes MD5 checksum df860a3649a5a9be02a83941d8a63169 Compiled from "TestClass.java" public class com.mxx.starter.test.TestClass minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #4.#15 // java/lang/Object."<init>":()V #2 = Fieldref #3.#16 // com/mxx/starter/test/TestClass.m:I #3 = Class #17 // com/mxx/starter/test/TestClass #4 = Class #18 // java/lang/Object #5 = Utf8 m #6 = Utf8 I #7 = Utf8 <init> #8 = Utf8 ()V #9 = Utf8 Code #10 = Utf8 LineNumberTable #11 = Utf8 test #12 = Utf8 ()I #13 = Utf8 SourceFile #14 = Utf8 TestClass.java #15 = NameAndType #7:#8 // "<init>":()V #16 = NameAndType #5:#6 // m:I #17 = Utf8 com/mxx/starter/test/TestClass #18 = Utf8 java/lang/Object { public com.mxx.starter.test.TestClass(); // Constructor descriptor: ()V flags: ACC_PUBLIC Code: // Stack =2, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: aload_0 5: iconst_5 6: putfield #2 // Field m:I 9: return LineNumberTable: line 10: 0 line 12: 4 public int test(); descriptor: ()I flags: ACC_PUBLIC Code: stack=2, locals=1, args_size=1 0: aload_0 1: getfield #2 // Field m:I 4: iconst_1 5: iadd 6: ireturn LineNumberTable: line 14: 0 } SourceFile: "TestClass.java"Copy the code

literal

Class loading, connection, initialization

Classes are loaded and unloaded out of memory, as shown in the diagram

loading

  1. Find and load the binary data of a class by its fully qualified name,
  2. To the runtime data structure of the method area,
  3. Create java.lang.Class objects on the heap to encapsulate the data structure of the Class in the method area and provide an interface to access the data structure in the Class

JVM native classloaders (loaded in combined-order)

  1. The bootstrapClassLoader prints null

It is responsible for loading the core class libraries in the <JAVA_HOME>/lib path or the jar packages with fixed class names in the path specified by the -xbootclasspath parameter into the memory. Bootstrap starts the class loader to load only classes whose package names start with Java, Javax, and Sun, which are provided by the JDK

  1. Jdk8 extensionClassLoader/platformClassLoader

Extension class loader loads files under jre/lib/ext/

  1. Application class loader (appClassLoader)

Java-classpath or -d java.class.path specifies the classpath path where the class library is loaded. The classpath directory is the sibling of the lib and classes generated JAR package or the target/classes directory viewed in idea

 URLClassLoader systemClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();

       for (URL url : systemClassLoader.getURLs()) {

           System.out.println("App path --"+url);
       }
Copy the code

  1. Custom class loaders

It is convenient to make some enhancements to the loaded classes. Class cannot be in the classpath directory because it complies with parental delegation


public class MyClassLoader extends ClassLoader{
Overwriting findClass follows the parent delegate model
    @Override
    protectedClass<? > findClass(String name)throws ClassNotFoundException {
        byte[] bytes = new byte[0];
        try {
            // Convert files to binary arrays
            bytes = loadClassDate(name);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return this.defineClass(name,bytes,0,bytes.length);
    }

    public byte[] loadClassDate(String name) throws IOException {
        byte[] bytes=null;
        ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
        name = name.replace("."."\ \");
        // The classes folder in the project root directory holds the compiled class files
        InputStream inputStream=new FileInputStream(new File("classes/"+name+".class"));
        int a=0;
        while((a=inputStream.read())! = -1){
            byteArrayOutputStream.write(a);
        }
        bytes = byteArrayOutputStream.toByteArray();
        returnbytes; }}Copy the code
  MyClassLoader myClassLoader=new MyClassLoader();
        try {
           // Clipping builds test. class from target to classes from project root
           System.out.println(myClassLoader.loadClass("com.example.demo.Test").getClassLoader());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
Copy the code

Parent delegation mechanism

If you need a class is loaded, then load the class class loader will be entrusted to the parent class to load, each layer, the recursion to the top, return to C if C is null, each layer to the findClass () method returns the C, when the parent class loader under its path to find such a full path name is returned directly, if not found, A subclass will try to load a class only when it is loaded. The parent refers to the parent class loader, and the parent-child relationship is not inherited, but composed (called).

// First, check if the class has already been loaded. > c = findLoadedClass(name); if (c == null) { long t0 = System.nanoTime(); try { if (parent ! = null) { c = parent.loadClass(name, false); } else {c = findBootstrapClassOrNull(name); }} Catch (ClassNotFoundException e) {// Thrown if ClassNotFoundException not found // from the non-null parent class loader } if (c == null) { // If still not found, then invoke findClass in order // to find the class. long t1 = System.nanoTime(); c = findClass(name); // This is the defining class loader; record the stats sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); sun.misc.PerfCounter.getFindClasses().increment(); } } if (resolve) { resolveClass(c); } return c; }Copy the code

The purpose of this is

  1. From the inside, the class is safe to load, because it has a hierarchy, so that if someone creates a java.lang.Object with bad code embedded in it, if we implement it in the parent delegate model, the only thing that ends up being loaded into the JVM is what’s in our Rt.jar. That is, the core base class code is protected.
  2. From the outside of the class to ensure that the referenced class has a public, consistent, different modules introduced in the public class load only once and is the same.

Break parental delegation

In some cases, the parent class cannot load the required class in its own scope, so it can only delegate to the subclass to load the required class file. For example, various SPIs, JDK defines interfaces, and different vendors implement them. DriverManager needs to load different database drivers. If the mysql Driver is an application class loader, you need to start the class loader to delegate subclasses to load the Driver implementation. Call Thread setContextClassLoader, getContextClassLoader to set the subclass loader, or the underlying implementation of the application class loader. The parental delegation model is also not strictly followed in hot deployment

The connection

Merges class binary data that has been read into memory into the JVM runtime environment

validation

The security of the Java language is guaranteed by the compiler. Classes that do not conform to the specification cannot be compiled correctly, but the virtual machine only recognizes the binary stream, and it does not care where the binary stream comes from. Of course, if it’s given by the compiler, it’s relatively safe. However, there is no guarantee that the binary byte stream is secure if it is obtained from another source.

Ensure that the information in the class file complies with all constraints in the JVM specification, including

  1. File structure

The loading process is the process of the binary byte stream from the external to the memory area. The binary byte stream is allowed to enter the method area only after the verification of this stage. The following verification indicates that the loading and verification are cross-referenced

  1. Metadata validation

Semantic analysis is performed on the described information to ensure that it conforms to JVM specification requirements, such as whether the data type is correct, whether the parent class is final if any, and whether inheritance is not allowed if any, such as whether the parent class is abstract, and if so, whether its abstract methods are overridden

  1. Bytecode verification

    By analyzing the data flow and control flow, ensure that the semantics are legal and logical, and verify the method body, such as whether there are any statements after the return

  2. Symbolic reference verification

    Check the matching of all kinds of information other than the class itself, such as whether the referenced class is accessible, whether the constant in the constant pool is valid, etc

Ensure that the information does not compromise VM security

To prepare

Allocates memory and initializes default values for static variables of a Class. In JDK7 and before, Class variables were stored in the method area. In JDK8 and after, Class variables are stored in the Java heap along with Class objects

parsing

Convert symbolic references in the constant pool defined by the class file to direct references. The new action is mainly for class or interface, field, class method, interface method, method type, method handle and call point qualifier

Symbol References (Symlxiuc References): symbol reference to a group of symbols to describe the referenced symbol, symbol can be any form of literal, as long as the use of unambiguous and non-conflict positioning to the target

Direct References: A Direct reference can be a pointer directly to the target, a relative offset, or a handle that can be indirectly located to the target

Initialize the

To assign an initial value to a static variable of a class executes a static code block or executes the class constructor < client > method

1. This method is by the compiler automatically collect all the class variables in the class assignment operation and static statements consolidation in a block of code to produce, collect the order is decided by the order of the statement in the source file, static blocks of code can only access to the class variables defined before it, but it can be defined in the class variable assignment. Because the variable has been loaded and initialized during the preparation phase, it can be assigned, but the initialization is not complete and cannot be accessed. As follows:

public class Test{
   static {
       i = 0; // The compiler passes
       System.out.print(i); // Failed to compile
   }
   static int i = 1;
}
Copy the code
 static {
        i = 0; // The compiler passes
    }
    static int i = 1;

    public static void main(String[] args) {
        System.out.println(Test2.i); / / 1
        
    }
Copy the code
  1. If a class has a parent class and is not initialized, the parent class is initialized first

3. If a class implements an interface or an interface inherits its parent interface, the parent interface is not initialized during initialization. The interface is initialized only when a variable in the interface is used for the first time or a method in the interface is called. Such as:

public interface Parent {
public static final String s="Parent" variable";

public void t1(a);
}
Copy the code
public class Test4 implements Parent{
    public static String ss="Static variables of a subclass";
static {
    System.out.println(ss);
}
    @Override
    public void t1(a) {
        System.out.println("Methods in interface");
    }

    public static void main(String[] args) {
        System.out.println(Test4.s);// Subclass static variable parent variable}}Copy the code
  1. Loading a class using a classloader does not trigger class initialization because it is not an active use of the class (it will be initialized if there is a default method).

When will it be initialized

  1. Instantiate a class
  2. A static variable or method that accesses a class or interface
  3. Reflect a class

Class<? > aClass = Class.forName(“com.mxx.starter.test.Test3”);

4. Initialize a subclass of an uninitialized class

Example 1

public class Test4 {
    public static Test4 test4=new Test4();
    public static int a=0;
    public static int b;

    public Test4(a) {
        a++;
        b++;
    }

    public static Test4 getInstance(a){
        return test4;
    }

    public  int getA(a) {
        return a;
    }

    public  int getB(a) {
        returnb; }}Copy the code
  Test4 instance = Test4.getInstance();
        System.out.println(instance.getA());/ / 0
        System.out.println(instance.getB());/ / 1
Copy the code

Int a=0; int a=0; Constructor a=1,b=1,a is assigning 0,b is not overwriting assignment,a =0,b=1

Case 2

public class Test4 {
    public static int a=0;
    public static int b;
    public static Test4 test4=new Test4();

    public Test4(a) {
        a++;
        b++;
    }

    public static Test4 getInstance(a){
        return test4;
    }

    public  int getA(a) {
        return a;
    }

    public  int getB(a) {
        returnb; }}Copy the code
  Test4 instance = Test4.getInstance();
        System.out.println(instance.getA());/ / 1
        System.out.println(instance.getB());/ / 1
Copy the code

Analysis: Refer to

Does not cause initialization

A subclass refers to a static variable of its parent class, and the subclass is not initialized

Access a constant of a subclass, not initialized

Instantiate an array of classes

uninstall

Classes loaded by the JVM’s native classloader are not unloaded (so they are loaded only once), whereas classes loaded by a custom classloader can be unloaded

Memory management

An overview of

Program counter (PC register)

Thread private, used to store the address of the program to execute the next instruction, the value of the local method is undefined, the only area that does not oom

The virtual machine stack

Describe the memory model of each thread of method execution, each method execution creates a stack frame synchronously, multiple stack frames form a stack, each frame stores a local variable table of a method, operand stack (the inbound and outbound behavior of a method for a series of operations), method return address, Dynamic concatenation (each stack frame contains a reference to the method that the stack frame belongs to in the run-time constant pool). When a method is called, a frame is created and pushed, and when the method exits, the top pointer is modified and the frame is destroyed. Local variables are stored in slots that store 32 bits of data. The advantages of these slots are fast access, while the disadvantages of these slots store the size of data, and their lifetime is determined at compile time

Local method stack

The role of Native Method Stacks is very similar to that of the virtual machine stack, except that the virtual machine stack performs Java methods (i.e. bytecodes) for the virtual machine, whereas the Native Method stack services the Native methods used by the virtual machine.

Methods area

The Method Area, like the Java heap, is an Area of memory shared by threads that stores data such as type information that has been loaded by the virtual machine, constants, static variables, and code caches compiled by the just-in-time compiler. Also called non-heap. Starting with JDK8, use the local memory meta-space instead. Literal and symbolic references in the class file are stored in the runtime constant pool in the method area after the class is loaded. In general, direct references translated from symbolic references are also stored in the constant pool. New constants can also be pooled at run time, as in the string.intern () method

Static variables and constants are stored in the method area, that is, static area member variables are stored in heap memory, and local variables are stored in stack memory.

The heap

Threads share the objects and arrays they create, dynamically allocate memory at run time and do garbage collection

Generation idea of heap memory structure

The new generation stores newly allocated objects, and the objects that the new generation does not recycle are copied to the old generation. The old generation stores much older objects than the new generation, and the old generation also stores large objects

Total heap size = New generation + old age

Cenozoic =Eden region + survival region

In the previous persistent generation, the area used to store the original information about the Class Method was stored in the meta-space starting in JDK8, which was not in the VIRTUAL machine, but in the local memory used

Objects in memory layout include

Object header instance data and alignment padding

Object headers include

Mark Word stores the running state of the object itself, such as the lock status identifier, gc generation age, hashCode and other types of Pointers to the object's class metadata, using this pointer to determine which class instance the object isCopy the code

Object access

Access via handle (indirect reference)

By pointer (direct reference)

The hotspot virtual machine mainly uses the second approach

Trace Parameter tracing

-version

-showversion

JVM startup prints version information and continues execution

-server

Start as a client (affects stack default memory size to provide performance)

-client

Start as a server

The following are the dump parameters for printing GC logs and OOM (-xlog was introduced after JDk9)

-XX:+HeapDumpOnOutOfMemoryError

-XX:HeapDumpPath=xxxx/heapdump.hprof

-XX:+PrintGC

-XX:+PrintGCDateStamps

-XX:+PrintGCDetails

-XX:+PrintGCTimeStamps

-XX:+PrintHeapAtGc

-Xms initializes the heap size

– Maximum value of the Xmx heap

-xMN sets the young generation size (initialized and Max), by default 3/8 of the entire heap

– XshowSettings: scope

Displays configuration items, including all, locale, properties, and VM

Example Set the initial memory and maximum memory of the meta-space to 512 MB

-XX:MaxMetaspaceSize=512m -XX:MetaspaceSize=512m

XMS XSX Default value:

If you download the 32-bit JDK, the default startup is client. In client mode, the initial and maximum heap size of the JVM is:

The JVM maximum heap size is half of the physical memory until 192MB of physical memory is reached, otherwise, the JVM maximum heap size is 1/4 of the physical memory until 1GB of physical memory is reached and 1GB of physical memory is calculated

For example, if your computer has 128MB of ram, the maximum heap size is 64MB, and if your physical memory is 1GB or greater, the maximum heap size is 256MB. The Java initial heap size is 1/64 of physical memory, but the minimum is 8MB.

If you downloaded the 64-bit JDK, the default startup is in client startup server mode: Similar to client mode, the difference is that the default value can be larger, for example, under a 32-bit JVM, the maximum heap size can be increased to 1GB if there is 4G or more physical memory, and under a 64-bit JVM, the maximum heap size can be increased to 32GB if there is 128GB or more physical memory.

– XX: HeapDumpOnOutOfMemoryError

-xx :newRatio The memory ratio of the old generation to the new generation is 2 by default. That is, the old generation :new generation =2:1

-xx :SurvivorRatio Eden and survivor ratio

– Call depth of the Xss method