JVM class loading mechanism - learning summary

Class loader initialization process

When we run a .class file in Java, firstly java.exe under Windows system invokes the underlying jvm.dll file to create a Java virtual machine (implemented in C++), thereby creating a jvm launcher instance sun.misc.Launcher.
Inside the construction method of Launcher, two class loaders are created, namely sun.misc.Launcher.ExtClassLoader (extended class loader) and sun.misc.Launcher.AppClassLoader (application class loader).
By default, the JVM uses the Launcher's getClassLoader() method to return an instance of the class loader, an instance of AppClassLoader, to load our application.

//Launcher的构造方法
public Launcher() {
    
    
    Launcher.ExtClassLoader var1;
    try {
    
    
        //构造扩展类加载器,在构造的过程中将其父加载器设置为null
        var1 = Launcher.ExtClassLoader.getExtClassLoader();
    } catch (IOException var10) {
    
    
        throw new InternalError("Could not create extension class loader", var10);
    }

    try {
    
    
        //构造应用类加载器,在构造的过程中将其父加载器设置为ExtClassLoader,
        //Launcher的loader属性值是AppClassLoader,我们一般都是用这个类加载器来加载我们自己写的应用程序
        this.loader = Launcher.AppClassLoader.getAppClassLoader(var1);
    } catch (IOException var9) {
    
    
        throw new InternalError("Could not create application class loader", var9);
    }

    Thread.currentThread().setContextClassLoader(this.loader);
    String var2 = System.getProperty("java.security.manager");
    。。。 。。。 //省略一些其他代码

}

Part of the source code of the parental delegation mechanism

The source code of the parent delegation mechanism of the application class loader AppClassLoader to load classes. The loadClass method of AppClassLoader will eventually call the loadClass method of its parent class ClassLoader. The general logic of this method is as follows: First, check whether the class with the specified name has been loaded.
If After loading, there is no need to load again, and return directly.
If this class has not been loaded, then judge whether there is a parent loader; if there is a parent loader, it will be loaded by the parent loader (that is, call parent.loadClass(name, false);). Or call bootstrap class loading device to load.
If neither the parent loader nor the bootstrap class loader finds the specified class, call the findClass method of the current class loader to complete class loading.

//ClassLoader的loadClass方法,里面实现了双亲委派机制
protected Class<?> loadClass(String name, boolean resolve)
    throws ClassNotFoundException
{
    
    
    synchronized (getClassLoadingLock(name)) {
    
    
        // 检查当前类加载器是否已经加载了该类
        Class<?> 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) {
    
    
                // ClassNotFoundException thrown if class 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();
                //都会调用URLClassLoader的findClass方法在加载器的类路径里查找并加载该类
                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;
    }
}

Guess you like

Origin blog.csdn.net/weixin_38746118/article/details/119581446