Java source code execution process

Explanation:

  1. Windows: bin/java.exe call jvm.dll Linux: Java call libjvm.so
  2. Create a bootloader instance (C++ implementation)
  3. C++ calls Java code to create the JVM Launcher instance sun.misc.Launcher.
  4. Sun. Misc. The Launcher. GetLauncher () for running your own loader this – > is AppClassLoader
  5. After getting the ClassLoader, call the loadClass(” A “) method to load the running class A
  6. After loading, execute the main method of class A
  7. End of program
  8. The JVM is destroyed

Class loading of loadClassprocess

 

Loading — — — — — — — — > > validation for analytical — — — — — — — — > > initialization — — — – > use — — — — > unloading

The first five are talked about a lot

  • Loading: Java bytecodes executed by the JVM must always be read on disk after compilation, so the first step must be loading the bytecode file.
  • Validation: The JVM can’t just read something and run it. You have an A.class that contains a bunch of things that the JVM specification doesn’t recognize and can’t execute. The next step is required to comply with the JVM specification, so the second step is to verify the correctness of the bytecode file.
  • To prepare: Allocates memory to static variables of the class and assigns default values. We might have some static variables in our class. Such aspublic static final int a = 12;You have to assign a default value of 0 to a, for examplepublic static User user = new User();Allocate memory to the static variable User and assign the default value null (final modified constant, directly assigned).
  • This is not easy to understand. What does this mean? Replace a symbolic reference with a direct reference. Symbolic reference? A direct quote? what ? Our class’s static methods, like the main method, actually have a name in Java called symbols. At this stage, some static methods (symbolic references, such as the main method) are replaced with Pointers or handles to the memory in which the data is stored (direct references). This is the static linking process (done during class loading). Dynamic linking is the replacement of symbolic references with direct references (such as a call to a normal method) that is done during program execution.
  • Initialize theAfter the above steps are done, this step is mainly to initialize the class static variable to the specified value, and execute the static code block. Like we did in step 2public static final int a = 12;The second step assigns a default value to the static variable, which is the time to assign 12. And static Userpublic static User user = new User();Instantiate User.

Note: If the main class is used by other classes during runtime, these classes will be gradually loaded. Classes in a JAR or WAR are not loaded all at once; they are loaded when used.

Example of class loading order:

 

public class TestDynamicLoad {

    static {
        System.out.println("Load a static code block in the TestDynamicLoad class");
    }

    public static void main(String[] args) {
        new A();
        System.out.println("Execute the code in the main method");
        B b = null;//B will not load unless new B() is called}}class A{
    static {
        System.out.println("Load A static code block in class A");
    }

    public A(a){
        System.out.println("Loading constructors in class A"); }}class B{
    static {
        System.out.println("Load a static code block in class B");
    }

    public B(a){
        System.out.println("Load constructors in class B"); }} The constructor of class A executes the code in mainCopy the code

Class loader

 

 

  • Bootloader: Load the core libraries that support the JVM in the JRE’s lib directory, such as rt.jar, charsets.jar, etc
  • Extension class loader: Is responsible for loading JAR classes from the Ext extension directory in the JRE’s lib directory that support the JVM
  • The application class loader is responsible for loading the class packages in the ClassPath path, mainly the classes that we write in our application
  • Custom loader: loads class packages in user-defined paths

Example class loader:

import com.sun.crypto.provider.DESKeyFactory;
import sun.misc.Launcher;
import java.net.URL;

public class TestJDKClassLoader {

    public static void main(String[] args) {

        System.out.println(String.class.getClassLoader());
        System.out.println(DESKeyFactory.class.getClassLoader().getClass().getName());
        System.out.println(TestJDKClassLoader.class.getClassLoader().getClass().getName());
        System.out.println();

        ClassLoader appClassLoader = ClassLoader.getSystemClassLoader();
        ClassLoader extClassloader = appClassLoader.getParent();
        ClassLoader bootstrapLoader = extClassloader.getParent();
        System.out.println("the bootstrapLoader : " + bootstrapLoader);
        System.out.println("the extClassloader : " + extClassloader);
        System.out.println("the appClassLoader : " + appClassLoader);
        System.out.println("AppClassLoader的父类加载器为ExtClassLoader,ExtClassLoader的父类加载器为null,null并不代表ExtClassLoader没有父类加载器,而是 BootstrapClassLoader");
        System.out.println();

        System.out.println("JRE的lib目录下的核心类库,bootstrapLoader加载以下文件:");
        URL[] urls = Launcher.getBootstrapClassPath().getURLs();
        for (int i = 0; i < urls.length; i++) {
            System.out.println(urls[i]);
        }
        System.out.println();

        System.out.println("JRE的lib目录下的ext扩展目录中的JAR类包,extClassloader加载以下文件:");
        String[] extClassloaderStr = System.getProperty("java.ext.dirs").split(";");
        for (String s : extClassloaderStr) {
            System.out.println(s);
        }
        System.out.println();

        System.out.println("加载ClassPath路径下的类包,appClassLoader加载以下文件:");
        String[] split = System.getProperty("java.class.path").split(";");
        for (String s : split) {
            System.out.println(s);
        }
    }

}

执行结果:

null
sun.misc.Launcher$ExtClassLoader
sun.misc.Launcher$AppClassLoader

the bootstrapLoader : null
the extClassloader : sun.misc.Launcher$ExtClassLoader@3dd3bcd
the appClassLoader : sun.misc.Launcher$AppClassLoader@14dad5dc
AppClassLoader的父类加载器为ExtClassLoader,ExtClassLoader的父类加载器为null,null并不代表ExtClassLoader没有父类加载器,而是 BootstrapClassLoader

JRE的lib目录下的核心类库,bootstrapLoader加载以下文件:
file:/D:/Environment/JDK/lib/resources.jar
file:/D:/Environment/JDK/lib/rt.jar
file:/D:/Environment/JDK/lib/sunrsasign.jar
file:/D:/Environment/JDK/lib/jsse.jar
file:/D:/Environment/JDK/lib/jce.jar
file:/D:/Environment/JDK/lib/charsets.jar
file:/D:/Environment/JDK/lib/jfr.jar
file:/D:/Environment/JDK/classes

JRE的lib目录下的ext扩展目录中的JAR类包,extClassloader加载以下文件:
D:\Environment\JDK\lib\ext
C:\Windows\Sun\Java\lib\ext

加载ClassPath路径下的类包,appClassLoader加载以下文件:
D:\Environment\JDK\jre\lib\charsets.jar
D:\Environment\JDK\jre\lib\deploy.jar
D:\Environment\JDK\jre\lib\ext\access-bridge-64.jar
D:\Environment\JDK\jre\lib\ext\cldrdata.jar
D:\Environment\JDK\jre\lib\ext\dnsns.jar
D:\Environment\JDK\jre\lib\ext\jaccess.jar
D:\Environment\JDK\jre\lib\ext\jfxrt.jar
D:\Environment\JDK\jre\lib\ext\localedata.jar
D:\Environment\JDK\jre\lib\ext\nashorn.jar
D:\Environment\JDK\jre\lib\ext\sunec.jar
D:\Environment\JDK\jre\lib\ext\sunjce_provider.jar
D:\Environment\JDK\jre\lib\ext\sunmscapi.jar
D:\Environment\JDK\jre\lib\ext\sunpkcs11.jar
D:\Environment\JDK\jre\lib\ext\zipfs.jar
D:\Environment\JDK\jre\lib\javaws.jar
D:\Environment\JDK\jre\lib\jce.jar
D:\Environment\JDK\jre\lib\jfr.jar
D:\Environment\JDK\jre\lib\jfxswt.jar
D:\Environment\JDK\jre\lib\jsse.jar
D:\Environment\JDK\jre\lib\management-agent.jar
D:\Environment\JDK\jre\lib\plugin.jar
D:\Environment\JDK\jre\lib\resources.jar
D:\Environment\JDK\jre\lib\rt.jar
D:\Project\Personal\website\reception\target\classes
D:\Environment\RepMaven\org\springframework\boot\spring-boot-starter\2.2.6.RELEASE\spring-boot-starter-2.2.6.RELEASE.jar
D:\Environment\RepMaven\org\springframework\boot\spring-boot\2.2.6.RELEASE\spring-boot-2.2.6.RELEASE.jar
D:\Environment\RepMaven\org\springframework\spring-context\5.2.5.RELEASE\spring-context-5.2.5.RELEASE.jar
D:\Environment\RepMaven\org\springframework\boot\spring-boot-autoconfigure\2.2.6.RELEASE\spring-boot-autoconfigure-2.2.6.RELEASE.jar
D:\Environment\RepMaven\org\springframework\boot\spring-boot-starter-logging\2.2.6.RELEASE\spring-boot-starter-logging-2.2.6.RELEASE.jar
D:\Environment\RepMaven\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar
D:\Environment\RepMaven\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar
D:\Environment\RepMaven\org\apache\logging\log4j\log4j-to-slf4j\2.12.1\log4j-to-slf4j-2.12.1.jar
D:\Environment\RepMaven\org\apache\logging\log4j\log4j-api\2.12.1\log4j-api-2.12.1.jar
D:\Environment\RepMaven\org\slf4j\jul-to-slf4j\1.7.30\jul-to-slf4j-1.7.30.jar
D:\Environment\RepMaven\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar
D:\Environment\RepMaven\org\springframework\spring-core\5.2.5.RELEASE\spring-core-5.2.5.RELEASE.jar
D:\Environment\RepMaven\org\springframework\spring-jcl\5.2.5.RELEASE\spring-jcl-5.2.5.RELEASE.jar
D:\Environment\RepMaven\org\yaml\snakeyaml\1.25\snakeyaml-1.25.jar
D:\Environment\RepMaven\org\springframework\boot\spring-boot-starter-web\2.2.6.RELEASE\spring-boot-starter-web-2.2.6.RELEASE.jar
D:\Environment\RepMaven\org\springframework\boot\spring-boot-starter-json\2.2.6.RELEASE\spring-boot-starter-json-2.2.6.RELEASE.jar
D:\Environment\RepMaven\com\fasterxml\jackson\core\jackson-databind\2.10.3\jackson-databind-2.10.3.jar
D:\Environment\RepMaven\com\fasterxml\jackson\core\jackson-core\2.10.3\jackson-core-2.10.3.jar
D:\Environment\RepMaven\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.10.3\jackson-datatype-jdk8-2.10.3.jar
D:\Environment\RepMaven\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.10.3\jackson-datatype-jsr310-2.10.3.jar
D:\Environment\RepMaven\com\fasterxml\jackson\module\jackson-module-parameter-names\2.10.3\jackson-module-parameter-names-2.10.3.jar
D:\Environment\RepMaven\org\springframework\boot\spring-boot-starter-validation\2.2.6.RELEASE\spring-boot-starter-validation-2.2.6.RELEASE.jar
D:\Environment\RepMaven\jakarta\validation\jakarta.validation-api\2.0.2\jakarta.validation-api-2.0.2.jar
D:\Environment\RepMaven\org\hibernate\validator\hibernate-validator\6.0.18.Final\hibernate-validator-6.0.18.Final.jar
D:\Environment\RepMaven\org\jboss\logging\jboss-logging\3.4.1.Final\jboss-logging-3.4.1.Final.jar
D:\Environment\RepMaven\org\springframework\spring-web\5.2.5.RELEASE\spring-web-5.2.5.RELEASE.jar
D:\Environment\RepMaven\org\springframework\spring-beans\5.2.5.RELEASE\spring-beans-5.2.5.RELEASE.jar
D:\Environment\RepMaven\org\springframework\spring-webmvc\5.2.5.RELEASE\spring-webmvc-5.2.5.RELEASE.jar
D:\Environment\RepMaven\org\springframework\spring-aop\5.2.5.RELEASE\spring-aop-5.2.5.RELEASE.jar
D:\Environment\RepMaven\org\springframework\spring-expression\5.2.5.RELEASE\spring-expression-5.2.5.RELEASE.jar
D:\Environment\RepMaven\org\apache\tomcat\embed\tomcat-embed-core\9.0.33\tomcat-embed-core-9.0.33.jar
D:\Environment\RepMaven\org\apache\tomcat\embed\tomcat-embed-el\9.0.33\tomcat-embed-el-9.0.33.jar
D:\Environment\RepMaven\org\apache\tomcat\embed\tomcat-embed-jasper\9.0.33\tomcat-embed-jasper-9.0.33.jar
D:\Environment\RepMaven\org\eclipse\jdt\ecj\3.18.0\ecj-3.18.0.jar
D:\Environment\RepMaven\jstl\jstl\1.2\jstl-1.2.jar
D:\Environment\RepMaven\mysql\mysql-connector-java\5.1.47\mysql-connector-java-5.1.47.jar
D:\Environment\RepMaven\tk\mybatis\mapper-spring-boot-starter\2.1.5\mapper-spring-boot-starter-2.1.5.jar
D:\Environment\RepMaven\org\springframework\boot\spring-boot-starter-jdbc\2.2.6.RELEASE\spring-boot-starter-jdbc-2.2.6.RELEASE.jar
D:\Environment\RepMaven\com\zaxxer\HikariCP\3.4.2\HikariCP-3.4.2.jar
D:\Environment\RepMaven\org\springframework\spring-jdbc\5.2.5.RELEASE\spring-jdbc-5.2.5.RELEASE.jar
D:\Environment\RepMaven\org\mybatis\mybatis\3.4.6\mybatis-3.4.6.jar
D:\Environment\RepMaven\org\mybatis\mybatis-spring\1.3.2\mybatis-spring-1.3.2.jar
D:\Environment\RepMaven\tk\mybatis\mapper-core\1.1.5\mapper-core-1.1.5.jar
D:\Environment\RepMaven\javax\persistence\persistence-api\1.0\persistence-api-1.0.jar
D:\Environment\RepMaven\tk\mybatis\mapper-base\1.1.5\mapper-base-1.1.5.jar
D:\Environment\RepMaven\tk\mybatis\mapper-weekend\1.1.5\mapper-weekend-1.1.5.jar
D:\Environment\RepMaven\tk\mybatis\mapper-spring\1.1.5\mapper-spring-1.1.5.jar
D:\Environment\RepMaven\tk\mybatis\mapper-extra\1.1.5\mapper-extra-1.1.5.jar
D:\Environment\RepMaven\tk\mybatis\mapper-spring-boot-autoconfigure\2.1.5\mapper-spring-boot-autoconfigure-2.1.5.jar
D:\Environment\RepMaven\com\alibaba\druid-spring-boot-starter\1.1.10\druid-spring-boot-starter-1.1.10.jar
D:\Environment\RepMaven\com\alibaba\druid\1.1.10\druid-1.1.10.jar
D:\Environment\RepMaven\org\slf4j\slf4j-api\1.7.30\slf4j-api-1.7.30.jar
D:\Environment\RepMaven\org\mybatis\generator\mybatis-generator-core\1.3.3\mybatis-generator-core-1.3.3.jar
D:\Environment\RepMaven\io\springfox\springfox-swagger2\2.7.0\springfox-swagger2-2.7.0.jar
D:\Environment\RepMaven\io\swagger\swagger-annotations\1.5.13\swagger-annotations-1.5.13.jar
D:\Environment\RepMaven\io\swagger\swagger-models\1.5.13\swagger-models-1.5.13.jar
D:\Environment\RepMaven\com\fasterxml\jackson\core\jackson-annotations\2.10.3\jackson-annotations-2.10.3.jar
D:\Environment\RepMaven\io\springfox\springfox-spi\2.7.0\springfox-spi-2.7.0.jar
D:\Environment\RepMaven\io\springfox\springfox-core\2.7.0\springfox-core-2.7.0.jar
D:\Environment\RepMaven\net\bytebuddy\byte-buddy\1.10.8\byte-buddy-1.10.8.jar
D:\Environment\RepMaven\io\springfox\springfox-schema\2.7.0\springfox-schema-2.7.0.jar
D:\Environment\RepMaven\io\springfox\springfox-swagger-common\2.7.0\springfox-swagger-common-2.7.0.jar
D:\Environment\RepMaven\io\springfox\springfox-spring-web\2.7.0\springfox-spring-web-2.7.0.jar
D:\Environment\RepMaven\org\reflections\reflections\0.9.11\reflections-0.9.11.jar
D:\Environment\RepMaven\org\javassist\javassist\3.21.0-GA\javassist-3.21.0-GA.jar
D:\Environment\RepMaven\com\google\guava\guava\18.0\guava-18.0.jar
D:\Environment\RepMaven\com\fasterxml\classmate\1.5.1\classmate-1.5.1.jar
D:\Environment\RepMaven\org\springframework\plugin\spring-plugin-core\1.2.0.RELEASE\spring-plugin-core-1.2.0.RELEASE.jar
D:\Environment\RepMaven\org\springframework\plugin\spring-plugin-metadata\1.2.0.RELEASE\spring-plugin-metadata-1.2.0.RELEASE.jar
D:\Environment\RepMaven\org\mapstruct\mapstruct\1.1.0.Final\mapstruct-1.1.0.Final.jar
D:\Environment\RepMaven\io\springfox\springfox-swagger-ui\2.7.0\springfox-swagger-ui-2.7.0.jar
D:\Environment\RepMaven\org\projectlombok\lombok\1.18.12\lombok-1.18.12.jar
D:\Environment\RepMaven\redis\clients\jedis\3.1.0\jedis-3.1.0.jar
D:\Environment\RepMaven\org\apache\commons\commons-pool2\2.7.0\commons-pool2-2.7.0.jar
D:\Environment\RepMaven\org\springframework\boot\spring-boot-starter-amqp\2.2.6.RELEASE\spring-boot-starter-amqp-2.2.6.RELEASE.jar
D:\Environment\RepMaven\org\springframework\spring-messaging\5.2.5.RELEASE\spring-messaging-5.2.5.RELEASE.jar
D:\Environment\RepMaven\org\springframework\amqp\spring-rabbit\2.2.5.RELEASE\spring-rabbit-2.2.5.RELEASE.jar
D:\Environment\RepMaven\com\rabbitmq\amqp-client\5.7.3\amqp-client-5.7.3.jar
D:\Environment\RepMaven\org\springframework\amqp\spring-amqp\2.2.5.RELEASE\spring-amqp-2.2.5.RELEASE.jar
D:\Environment\RepMaven\org\springframework\retry\spring-retry\1.2.5.RELEASE\spring-retry-1.2.5.RELEASE.jar
D:\Environment\RepMaven\org\springframework\spring-tx\5.2.5.RELEASE\spring-tx-5.2.5.RELEASE.jar
D:\Environment\RepMaven\org\springframework\boot\spring-boot-configuration-processor\2.2.4.RELEASE\spring-boot-configuration-processor-2.2.4.RELEASE.jar
E:\SoftWare\IntelliJ IDEA 2019.1.1\lib\idea_rt.jar
C:\Users\root\.IntelliJIdea2019.1\system\captureAgent\debugger-agent.jar
Copy the code

Parent delegation mechanism

What is the parent delegate mechanism?

  • Simply say: first look for father to load, not by his son to load again.
  • Popularly speaking: when we need to load a class, we will first entrust the parent loader to find the target class, and then entrust the upper parent loader to load. If all the parent loaders can not find the target class in their own loading class path, they will find and load the target class in their own class loading path.
  • For example: AppClassLoader will first load the application class. AppClassLoader will first delegate the ExtClassLoader to load the application class. The extension classloader will then delegate the BootClassLoader to load the application class. When the top bootloader fails to find class A in its own class loading path, it will return the request to load class A. When the ExtClassLoader receives the reply, it will load it by itself. After searching for class A in its own class loading path for A long time, it cannot find class A. The application class loader looks for class A in its own class loading path and loads it.

Why design parental delegation?

  • Sandbox security: Self-written java.lang.String.class classes are not loaded, which prevents the core API library from being tampered with.
  • Avoid class reloading: When the parent has already loaded the class, there is no need for the child ClassLoader to load it again to ensure the uniqueness of the loaded class. * * * *

The application class loader AppClassLoader loads the source code for the parent delegate mechanism of the class

private final ClassLoader parent; protected Class<? > loadClass(String name, Boolean resolve)throws ClassNotFoundException{synchronized (getClassLoadingLock(name)) {// First, check whether the requested Class has been loaded Class<? > c = findLoadedClass(name); if (c == null) { long t0 = System.nanoTime(); try { if (parent ! C = parent.loadClass(name, false); C = findBootstrapClassOrNull(name); c = findBootstrapClassOrNull(name); }} Catch (ClassNotFoundException e) {if (c == null) {long t1 = system.nanotime (); C = findClass(name); // This is defining the class loader; Record statistics sun. Misc. PerfCounter. GetParentDelegationTime (). The addTime (t1 - t0); sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); sun.misc.PerfCounter.getFindClasses().increment(); } } if (resolve) { resolveClass(c); } return c; }}Copy the code

Execution steps:

  1. First, check to see if the class with the specified name has already been loaded. If it has been loaded, it does not need to be loaded again and returns directly.
  2. If this class has not been loaded, then check if there is a parent loader; If there is a parent loader, it is loaded either by the parent (that is, by calling parent. LoadClass (name, false)) or by calling the bootstrap class loader.
  3. If neither the parent nor the Bootstrap class loader can find the specified class, the findClass method of the current class loader is called to complete the class loading.

String class loading example:

package java.lang; /** * Description: Created by root on 2020/8/11 10:33 */ public class String {public static void Main (String[] args) {system.out.println (" my custom String class "); }} Execution result: Error: Main method not found in java.lang.String class, define main as: Public static void main (String [] args) or deployment headaches the application class must extend deployment headaches. The application. The applicationCopy the code

Java.lang.String is a fully qualified class named java.lang.String. The java.lang.String is a fully qualified class named java.lang.String. Java.lang.string does not have a main() method, so an error is reported. It’s a safety mechanism.

JVM class loading mechanism

  • When a Class loader is responsible for loading a Class, other classes that that Class depends on and references are also loaded by the Class loader, unless it is shown to be loaded using another Class loader
  • The parent delegate mechanism lets the parent class loader try to load the class first, and only tries to load the class from its own classpath if the parent class loader cannot load the class
  • The caching mechanism will ensure that all loaded classes will be cached. When a program needs to use a Class, the Class loader first looks for the Class in the cache. Only when the cache does not exist, the system will read the binary data corresponding to the Class, convert it into a Class object, and store it in the cache. Is that why you have to restart the JVM to make Class changes to take effect

Example of a custom class loader:

A custom ClassLoader simply inherits the java.lang.ClassLoader class, which has two core methods: loadClass(String, Boolean), which implements parental delegation, and findClass, which implements an empty method by default. So our custom classloader basically overrides the findClass method.