JVM virtual machine && class loading (1)

virtual machine

Introduction to Virtual Machine

The Java Virtual Machine (JVM) is an abstract computer that runs java programs. It is a specification of computer equipment and can be implemented in different ways. The java program can be implemented cross-platform by running in the JVM. Once compiled, it runs everywhere. Different operating systems have different JDK version, by calling the JNI method to achieve the method of calling different operating systems

graph LR A [java source file] B [class binary bytecode] C [JVM] D ((Java native interface)) F [windows native method] H [linux native method] I [macOS native method] A-.compile .-> B B-.Load .-> C C-.Open file .-> D D-.windows-JDK .-> F D-.linux-JDK .-> H D-.macOS-JDK .-> I

The Java virtual machine is not bound to the language including java. It is only bound to the specific binary file format of the Class file. The class file contains the virtual machine instruction set and symbol table and several other auxiliary information.

graph LR A [java program] B [JRuby program] C [Groovy program] D [java compiler] E [JRuby compiler] F [Groovy compiler] H [byte code] I [Java virtual machine] A-. * .java file .-> D B-. *. rb file .-> E C-. *. groovy file .-> F D-> H E-> H F-> H H-. *. class file .-> I

Virtual machine products

  1. Sun HotSpot(JVM)
  2. BEA JRocket
  3. IBM J9
  4. Microsoft JVM
  5. Google Android Dalvik

Class files

The Class file is a binary stream with 8-bit basic units. The data is arranged in strict order in the Class file without any separators. If it exceeds 8 bits, it is stored in the high-order first.

Class file composition

  1. java virtual machine instruction set
  2. Symbol table
  3. Other auxiliary information

Constant pool

After the java code is compiled, the Class file does not save the various methods and the final layout of the fields in memory. Because the actual address of the referenced class is not known during compilation, it can only be replaced with a symbol description. When the virtual machine is really When running, you need to obtain the corresponding symbol reference from the constant pool of the class file, and then resolve the specific memory address during class creation or runtime

That is to say, when the class is loaded, a specific address must be allocated in memory, so that when it is resolved, the symbol reference can be replaced with the real address.

The constant pool of Class files mainly stores two types:

  • Literals Literals are constant concepts close to the Java language level, such as text strings, declaring final constant values, etc.
  • Symbolic references mainly include fully qualified names of classes and interfaces, field names and descriptors, method names and descriptors

Virtual machine class loading

Class loading into the JVM life space

graph LR A [Loading] B [Verification Verification] C [Preparation Preparation] D [Resolution] E [Initialization] F [Using Using] G [Unloading] A-> B D-> E E-- > F F-> G subgraph connect B-> C C-> D end

load

What the loading process does is:

  • Get binary byte stream
  • The static storage structure is transformed into the runtime data structure of the method area
  • Generate a class object in the java heap object as the entrance of the method area

There are ways to get a stream of binary bytes in Java

  • Obtained from Zip, Jar, War and other format files
  • Get Applet app from the web
  • Runtime calculation and generation, dynamic proxy technology
  • The JSP application generates the corresponding Class class

verification

Verification is the first step of the connection. To ensure that the information contained in the byte stream in the Class file meets the requirements of the JVM, the verification phase is roughly divided into the following stages

  • File format verification verifies that the file ID is correct, whether the version number can match the current JVM, and whether the constants in the constant pool have unsupported types.After this stage of verification, the byte stream will enter the method area for storage. The subsequent verification is only based on the storage structure verification of the method area, and will not verify the byte stream
  • Metadata verification is mainly to analyze the semantics of the bytecode description, to ensure the specification of the symbol java language, class inheritance, abstract class implementation, etc.
  • Bytecode verification
  • Symbol reference verification This stage occurs when the symbol reference is replaced with a direct reference, to verify the matching check of the symbol reference, etc.

ready

The preparation stage is to allocate memory to the class and set the initialization Clint of the class variables. The memory used by these variables is allocated in the method area, but the memory allocation of the class variables (Static modified) does not include instance variables. As the class is instantiated, it is allocated in the heap

: Initialization of the class of the parent static variable parent class static block subclass static variable subclass static block

: Initialization of objects Initialize variables of parent class, constructor of parent class. . . . . .

Parsing

The purpose of resolution is to replace the symbol references in the constant pool with direct references

Field analysis

class A extends B implements C{
    private String str; //字段的解析
}
graph TB A {A can match} B {B can match} C {C can match} A-> | Yes | E [End] A-> | No | C subgraph interface C-> | Yes | F (End) end subgraph Parent C-> | No | B B-> | Yes | I (End) B-> | No | J ((throw exception)) end

Class method analysis

  • Find this category first
  • Then recursively search in the parent class
  • List of interfaces implemented in the class and their parent interfaces

Interface method analysis

  • Find this interface first
  • Find recursively in the parent interface of the interface

Class loader

Obtain the binary byte stream describing the class by the fully qualified name of the class, and put the action in this stage of loading the class outside the virtual machine to implement, so that the application can decide if it wants to get the class it needs to achieve Be a class loader.
There is an abstract class ClassLoader class in Java.
The core summary of the ClassLoader.loadClass class is:

  • Only one thread can load a class at a time
  • Before loading the class, it will check whether it has been loaded. Only those that have not been loaded can be loaded.
  • The one that can be loaded by the parent loader will never be handed over to the child loader. Why is this so as to ensure safety, for example, if you write a java underlying class with the same name, such as java.util.ArrayList, through the child loader to the memory , Is n’t that messy? When the time comes, a virus code will be implanted and the person who uses it will not be GG.
  • The child loader will only load the parent loader if it cannot be loaded.

Loader type

From the perspective of the JVM, there are only 2 class loaders. One is that the Bootstrap ClassLoader is implemented by the C ++ language. There is another kind of class loader, which is implemented by java language, independent of JVM, all inherit java.lang.ClassLoader

If we look at it from our development perspective, it is divided into 3 class loaders:

  • Bootstrap ClassLoader starts the class loader, which is responsible for loading the class libraries under Java_Home / lib into memory. Because of the local implementation details involved in the virtual machine, all of our developers cannot get a reference to the class loader.
  • Extension ClassLoader The extension class loader is responsible for loading Java_Home / lib / ext or the class specified by the system variable java.ext.dirs into the memory
//Launcher.class文件中
static class ExtClassLoader extends URLClassLoader {
        private static volatile Launcher.ExtClassLoader instance;

        public static Launcher.ExtClassLoader getExtClassLoader() throws IOException {
            if (instance == null) {
                Class var0 = Launcher.ExtClassLoader.class;
                synchronized(Launcher.ExtClassLoader.class) {
                    if (instance == null) {
                        instance = createExtClassLoader();
                    }
                }
            }

            return instance;
        }
     ....        
}
  • Application ClassLoader application class chicken loader, which is responsible for loading the class library specified in the system path ClassPath into memory, this class loader is
    the return value of the getSystemClassLoader static method in the ClassLoader class
 //java/lang/ClassLoader.java 文件中
 public static ClassLoader getSystemClassLoader() {
        initSystemClassLoader();
        if (scl == null) {
            return null;
        }
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            checkClassLoaderPermission(scl, Reflection.getCallerClass());
        }
        return scl;
    }
graph BT A[Bootstrap加载器] B[ExtClassLoader] C[AppClassLoader] D[UseClassLoader1] F[UseClassLoader2] B --> A subgraph 非JVM C --> B D --> C F --> C end

If you are interested, you can perform it yourself

String appClassLoaderPath = System.getProperty("java.class.path");
System.out.println(appClassLoaderPath);
String extClassLoaderPath = System.getProperty("java.ext.dirs");
System.out.println(extClassLoaderPath);
String bootClassLoaderPath = System.getProperty("sun.boot.class.path");
System.out.println(bootClassLoaderPath);

Parent delegation

What is parent delegation

  • If a class loader receives a class load request, the loader will not load, but will throw the request to the parent class loader, so all class load requests will reach the top class loader
  • Only when the parent class loader cannot find the required class within its scope, the result will be fed back to the child loader, and the child loader is trying to load itself

How to interrupt

Write a class loader yourself and rewrite the loadClass method!

Why use parent delegation

  • For any class, it is necessary to establish its uniqueness in the Java virtual machine by the class loader that loads it and the class itself. Each class loader has an independent class namespace. To determine whether two classes are "equal", it must be under the premise that the two classes are loaded by the same class loader.
  • Based on the parent delegation model design, then the problem of the basic class in Java, such as the Object class repeated many times will not exist, because after passing through layers, the loading request will eventually be responded by BootstrapClassLoader. There will be only one Object class loaded, otherwise if the user writes a java.lang.Object class and puts it in the ClassPath, there will be many Object classes, so that the most basic behavior in the Java type system can not be Guarantee, the application will also be a mess.

Guess you like

Origin www.cnblogs.com/burg-xun/p/12689079.html