jvm雙親委派機制

JVM整體加載流程
JVM整體流程如上圖所示.java類的加載是有加載器來進行的.JVM中有以下幾種類加載器:
1.引導類加載器BootstrapClassLoader :負責加載支撐JVM運行的位於JRE的lib目錄核心類庫,比如rt.jar,charsets.jar等
2.擴展類加載器ExtClassLoader :負責加載支撐JVM運行的位於JRE的lib目錄下的ext擴展目錄下的JAR包
3.應用程序類加載器:負責加載ClassPath路徑下的類包
4.自定義加載器:負責加載用戶自定義路徑下的類包.

 public Launcher() {
        Launcher.ExtClassLoader var1;
        try {
            var1 = Launcher.ExtClassLoader.getExtClassLoader();
        } catch (IOException var10) {
            throw new InternalError("Could not create extension class loader", var10);
        }

        try {
            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");
        if (var2 != null) {
            SecurityManager var3 = null;
            if (!"".equals(var2) && !"default".equals(var2)) {
                try {
                    var3 = (SecurityManager)this.loader.loadClass(var2).newInstance();
                } catch (IllegalAccessException var5) {
                } catch (InstantiationException var6) {
                } catch (ClassNotFoundException var7) {
                } catch (ClassCastException var8) {
                }
            } else {
                var3 = new SecurityManager();
            }

            if (var3 == null) {
                throw new InternalError("Could not create SecurityManager: " + var2);
            }

            System.setSecurityManager(var3);
        }

    }

注意:ExtClassLoader 和AppClassLoader直接並沒有繼承關係只是AppClassLoader中的parent屬性是ExtClassLoader

雙親委派機制流程圖解
雙親委派源碼實現機制:ClassLoader.loadClass();

protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                	//從第一張圖中可以看出AppClassLoader.parent屬性值ExtClassLoader
                   // ExtClassLoader的parent屬性值爲null
                    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();
                    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;
        }
    }

該方法大體邏輯是:
1 首先,檢查一下指定名稱的類是否已經加載過,如果加載過了,就不需要再加載,直接 返回。
2. 如果此類沒有加載過,那麼,再判斷一下是否有父加載器;如果有父加載器,則由父加 載器加載(即調用parent.loadClass(name, false);).或者是調用bootstrap類加載器來加 載。
3. 如果父加載器及bootstrap類加載器都沒有找到指定的類,那麼調用當前類加載器的 findClass方法來完成類加載。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章