類加載器、雙親委派機制和沙箱安全機制


類加載器、雙親委派機制和沙箱安全機制

類加載器

作用:加載Class文件

類加載流程:

加載--->鏈接(驗證-->准備--->解析)---->初始化

  • JVM支持兩種類型的類加載器,分別為引導類加載器(Bootstrap Class Loader)和自定義類加載器(User-Defined ClassLoader)

  • 從概念上來講,自定義類加載器一-般指的是程序中由開發人員自定義的一類,類加載器,但是Java虛擬機規范卻沒有這么定義,而是將所有派生於抽象類ClassLoader的類加載器都划分為自定義類加載器。

  • 無論類加載器的類型如何划分,在程序中我們最常見的類加載器始終只有3
    個, 如下所示:

    這4者之間的關系是包含關系,不是上下層,也不是子父類的繼承關系。可以看成等級關系

    自定義ClassLoader繼承樹關系(自定義類加載器是Java編寫,而引導類加載器是C++編寫)

  1. BootstrapClassLoader 啟動類(根/引導類)加載器----用於加載 :/jre/lib/rt.jar

    c/c++編寫,加載java核心庫 java.*,構造ExtClassLoaderAppClassLoader。由於引導類加載器涉及到虛擬機本地實現細節,開發者無法直接獲取到啟動類加載器的引用,所以不允許直接通過引用進行操作

  2. ExtClassLoader 標准擴展類加載器-------用於加載 :/jre/lib/ext/*

    java編寫,由sun.misc.Launcher$ExtClassLoader實現,加載擴展庫,如classpath中的jrejavax.*或者java.ext.dir 指定位置中的類,開發者可以直接使用標准擴展類加載器。

  3. AppClassLoader 應用程序加載器,也叫系統類加載器

    java編寫,加載程序所在的目錄,如user.dir所在的位置的class

    源碼分析

    protected Class<?> loadClass(String name, boolean resolve)
                throws ClassNotFoundException
        {
            synchronized (getClassLoadingLock(name)) {
                // 首先檢查這個classsh是否已經加載過了
                Class<?> c = findLoadedClass(name);
                if (c == null) {
                    long t0 = System.nanoTime();
                    try {
                        // c==null表示沒有加載,如果有父類的加載器則讓父類加載器加載
                        if (parent != null) {
                            c = parent.loadClass(name, false);
                        } else {
                            //如果父類的加載器為空 則說明遞歸到bootStrapClassloader了
                            //bootStrapClassloader比較特殊無法通過get獲取
                            c = findBootstrapClassOrNull(name);
                        }
                    } catch (ClassNotFoundException e) {}
                    if (c == null) {
                        //如果bootstrapClassLoader 仍然沒有加載過,則遞歸回來,嘗試自己去加載class
                        long t1 = System.nanoTime();
                        c = findClass(name);
                        sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                        sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                        sun.misc.PerfCounter.getFindClasses().increment();
                    }
                }
                if (resolve) {
                    resolveClass(c);
                }
                return c;
            }
        }
    

    獲取類加載器的方式

    • 方式一:獲取當前類的ClassLoader
      • clazz. getClassLoader ()
    • 方式二:獲取當前線程上下文的ClassLoader
      • Thread. currentThread() .getContextClassLoader ()
    • 方式三:獲取系統的ClassLoader
      • ClassLoader.getSystemClassLoader ()
    • 方式四:獲取調用者的ClassLoader
      • DriverManager.getCallerClassLoader ()

雙親委派機制

  1. 類加載器收到類加載請求

  2. 將這個請求委托給父類加載器去完成,一直向上委托,直到啟動類加載器。

  3. 啟動類加載器檢查是否能夠加載這個類,能加載就進行加載,不能則拋出異常,通知子類進行加載

  4. 若應用程序加載器也不能加載則拋出Class Not Found~異常

雙親委派機制的作用:

1、防止重復加載同一個.class。通過委托去向上面問一問,加載過了,就不用再加載一遍。保證數據安全。
2、保證核心.class不能被篡改。通過委托方式,不會去篡改核心.clas,即使篡改也不會去加載,即使加載也不會是同一個.class對象了。不同的加載器加載同一個.class也不是同一個Class對象。這樣保證了Class執行安全。

沙箱安全機制

參考:https://blog.csdn.net/qq_30336433/article/details/83268945
上一篇:JVM的體系結構
下一篇:JVM的生命周期和發展歷程


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM