最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JVM的類加載器和雙親委派模式你了解嗎

 更新時(shí)間:2022年03月13日 16:57:14   作者:weixin_45379261  
這篇文章主要為大家詳細(xì)介紹了JVM類加載器和雙親委派模式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

類加載器

Java虛擬機(jī)設(shè)計(jì)團(tuán)隊(duì)有意把類加載階段中的“通過一個(gè)類的全限定名來獲取描述該類的二進(jìn)制字節(jié)流”這個(gè)動(dòng)作放到Java虛擬機(jī)外部去實(shí)現(xiàn),以便讓應(yīng)用程序自己決定如何去獲取所需的類。實(shí)現(xiàn)這個(gè)動(dòng)作的代碼被稱為“類加載器”(ClassLoader)。

對于任意一個(gè)類,都必須由加載它的類加載器和這個(gè)類本身一起共同確立其在Java虛擬機(jī)中的唯一性,每一個(gè)類加載器,都擁有一個(gè)獨(dú)立的類名稱空間。這句話可以表達(dá)得更通俗一些:比較兩個(gè)類是否“相等”,只有在這兩個(gè)類是由同一個(gè)類加載器加載的前提下才有意義,否則,即使這兩個(gè)類來源于同一個(gè)Class文件,被同一個(gè)Java虛擬機(jī)加載,只要加載它們的類加載器不同,那這兩個(gè)類就必定不相等

名稱加載的類說明
Bootstrap ClassLoader(啟動(dòng)類加載器)JAVA_HOME/jre/lib無法直接訪問
Extension ClassLoader(拓展類加載器)JAVA_HOME/jre/lib/ext上級為Bootstrap,顯示為null
Application ClassLoader(應(yīng)用程序類加載器)classpath上級為Extension
自定義類加載器自定義上級為Application

1、啟動(dòng)類加載器

可通過在控制臺輸入指令,使得類被啟動(dòng)類加器加載,它是用C++寫的,看不到源碼;其他類加載器是用Java寫的,說白了就是一些Java類,比如擴(kuò)展類加載器、應(yīng)用類加載器。

//查詢所有被啟動(dòng)類加載器加載的類
URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();
for (URL url : urls) {
    System.out.println(url);
}
//查詢到的結(jié)果
file:/C:/Program%20Files/Java/jre1.8.0_131/lib/resources.jar
file:/C:/Program%20Files/Java/jre1.8.0_131/lib/rt.jar
file:/C:/Program%20Files/Java/jre1.8.0_131/lib/sunrsasign.jar
file:/C:/Program%20Files/Java/jre1.8.0_131/lib/jsse.jar
file:/C:/Program%20Files/Java/jre1.8.0_131/lib/jce.jar
file:/C:/Program%20Files/Java/jre1.8.0_131/lib/charsets.jar
file:/C:/Program%20Files/Java/jre1.8.0_131/lib/jfr.jar
file:/C:/Program%20Files/Java/jre1.8.0_131/classes

由上可以看出啟動(dòng)類加載的都是jre和jre/lib目錄下的核心庫,具體路徑要看你的jre安裝在哪里。

2、拓展類加載器

如果classpath和JAVA_HOME/jre/lib/ext 下有同名類,加載時(shí)會使用拓展類加載器加載。當(dāng)應(yīng)用程序類加載器發(fā)現(xiàn)拓展類加載器已將該同名類加載過了,則不會再次加載

URL[] urls = ((URLClassLoader) ClassLoader.getSystemClassLoader().getParent()).getURLs();
for (URL url : urls) {
    System.out.println(url);
}
file:/C:/Program%20Files/Java/jre1.8.0_131/lib/ext/access-bridge-64.jar
file:/C:/Program%20Files/Java/jre1.8.0_131/lib/ext/cldrdata.jar
file:/C:/Program%20Files/Java/jre1.8.0_131/lib/ext/dnsns.jar
file:/C:/Program%20Files/Java/jre1.8.0_131/lib/ext/dns_sd.jar
file:/C:/Program%20Files/Java/jre1.8.0_131/lib/ext/jaccess.jar
file:/C:/Program%20Files/Java/jre1.8.0_131/lib/ext/jfxrt.jar
file:/C:/Program%20Files/Java/jre1.8.0_131/lib/ext/localedata.jar
file:/C:/Program%20Files/Java/jre1.8.0_131/lib/ext/nashorn.jar
file:/C:/Program%20Files/Java/jre1.8.0_131/lib/ext/sunec.jar
file:/C:/Program%20Files/Java/jre1.8.0_131/lib/ext/sunjce_provider.jar
file:/C:/Program%20Files/Java/jre1.8.0_131/lib/ext/sunmscapi.jar
file:/C:/Program%20Files/Java/jre1.8.0_131/lib/ext/sunpkcs11.jar
file:/C:/Program%20Files/Java/jre1.8.0_131/lib/ext/zipfs.jar

這些類庫具體是什么不重要,只需要知道不同的類庫可能是被不同的類加載器加載的。

3、應(yīng)用程序類加載器

URL[] urls = ((URLClassLoader) ClassLoader.getSystemClassLoader()).getURLs();
for (URL url : urls) {
    System.out.println(url);
}
file:/{項(xiàng)目工程目錄}/bin/

這是當(dāng)前java工程的bin目錄,也就是我們自己的Java代碼編譯成的class文件所在。

4、雙親委派模式

雙親委派模式,調(diào)用類加載器ClassLoader 的 loadClass 方法時(shí),查找類的規(guī)則。

loadClass源碼

protected Class<?> loadClass(String name, boolean resolve)
    throws ClassNotFoundException
{
    synchronized (getClassLoadingLock(name)) {
        // 首先查找該類是否已經(jīng)被該類加載器加載過了
        Class<?> c = findLoadedClass(name);
        //如果沒有被加載過
        if (c == null) {
            long t0 = System.nanoTime();
            try {
                //看是否被它的上級加載器加載過了 Extension的上級是Bootstarp,但它顯示為null
                if (parent != null) {
                    c = parent.loadClass(name, false);
                } else {
                    //看是否被啟動(dòng)類加載器加載過
                    c = findBootstrapClassOrNull(name);
                }
            } catch (ClassNotFoundException e) {
                // ClassNotFoundException thrown if class not found
                // from the non-null parent class loader
                //捕獲異常,但不做任何處理
            }
            if (c == null) {
                //如果還是沒有找到,先讓拓展類加載器調(diào)用findClass方法去找到該類,如果還是沒找到,就拋出異常
                //然后讓應(yīng)用類加載器去找classpath下找該類
                long t1 = System.nanoTime();
                c = findClass(name);
                // 記錄時(shí)間
                sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                sun.misc.PerfCounter.getFindClasses().increment();
            }
        }
        if (resolve) {
            resolveClass(c);
        }
        return c;
    }
}

有一個(gè)描述類加載器加載類過程的術(shù)語:雙親委派模型。然而這是一個(gè)很有誤導(dǎo)性的術(shù)語,它應(yīng)該叫做單親委派模型(Parent-Delegation Model)。但是沒有辦法,大家都已經(jīng)這樣叫了。所謂雙親委派,這個(gè)親就是指ClassLoader里的全局變量parent,也就是父加載器。

雙親委派的具體過程如下:

  • 當(dāng)一個(gè)類加載器接收到類加載任務(wù)時(shí),先查緩存里有沒有,如果沒有,將任務(wù)委托給它的父加載器去執(zhí)行。
  • 父加載器也做同樣的事情,一層一層往上委托,直到最頂層的啟動(dòng)類加載器為止。
  • 如果啟動(dòng)類加載器沒有找到所需加載的類,便將此加載任務(wù)退回給下一級類加載器去執(zhí)行,而下一級的類加載器也做同樣的事情。
  • 如果最底層類加載器仍然沒有找到所需要的class文件,則拋出異常。
  • 所以是一條線傳上再傳下,并沒有什么“雙親”。

在這里插入圖片描述

為什么要雙親委派?

:確保類的全局唯一性。

如果你自己寫的一個(gè)類與核心類庫中的類重名,會發(fā)現(xiàn)這個(gè)類可以被正常編譯,但永遠(yuǎn)無法被加載運(yùn)行。因?yàn)槟銓懙倪@個(gè)類不會被應(yīng)用類加載器加載,而是被委托到頂層,被啟動(dòng)類加載器在核心類庫中找到了。如果沒有雙親委托機(jī)制來確保類的全局唯一性,誰都可以編寫一個(gè)java.lang.Object類放在classpath下,那應(yīng)用程序就亂套了。

從安全的角度講,通過雙親委托機(jī)制,Java虛擬機(jī)總是先從最可信的Java核心API查找類型,可以防止不可信的類假扮被信任的類對系統(tǒng)造成危害。

5、自定義類加載器

如果我們自己去實(shí)現(xiàn)一個(gè)類加載器,基本上就是繼承ClassLoader之后重寫findClass方法,且在此方法的最后調(diào)包defineClass。

5.1、使用場景

  • 想加載非 classpath 隨意路徑中的類文件
  • 通過接口來使用實(shí)現(xiàn),希望解耦時(shí),常用在框架設(shè)計(jì)
  • 這些類希望予以隔離,不同應(yīng)用的同名類都可以加載,不沖突,常見于 tomcat 容器

5.2、步驟

  • 繼承ClassLoader父類
  • 要遵從雙親委派機(jī)制,重寫 ?ndClass 方法
    • 不是重寫loadClass方法,否則不會走雙親委派機(jī)制
  • 讀取類文件的字節(jié)碼
  • 調(diào)用父類的 de?neClass 方法來加載類
  • 使用者調(diào)用該類加載器的 loadClass 方法
protected Class<?> findClass(final String name) throws ClassNotFoundException {
    // 1、安全檢查
    // 2、根據(jù)絕對路徑把硬盤上class文件讀入內(nèi)存
    byte[] raw = getBytes(name); 
    // 3、將二進(jìn)制數(shù)據(jù)轉(zhuǎn)換成class對象
    return defineClass(raw);
}

總結(jié)

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容! 

相關(guān)文章

  • Java Home變量的詳細(xì)配置操作步驟

    Java Home變量的詳細(xì)配置操作步驟

    用到Java項(xiàng)目的時(shí)候,有時(shí)候要用到Java_home,這個(gè)需要在系統(tǒng)配置中配置一下,如何操作呢?以下為詳細(xì)的圖文步驟,感興趣的朋友跟隨小編一起看看吧
    2023-11-11
  • scala 匿名函數(shù)案例詳解

    scala 匿名函數(shù)案例詳解

    Scala支持一級函數(shù),函數(shù)可以用函數(shù)文字語法表達(dá),即(x:Int)=> x + 1,該函數(shù)可以由一個(gè)叫作函數(shù)值的對象來表示,這篇文章主要介紹了scala 匿名函數(shù)詳解,需要的朋友可以參考下
    2023-03-03
  • Springboot 配置RabbitMQ文檔的方法步驟

    Springboot 配置RabbitMQ文檔的方法步驟

    這篇文章主要介紹了Springboot 配置RabbitMQ文檔的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Java面試題沖刺第二十七天--JVM2

    Java面試題沖刺第二十七天--JVM2

    這篇文章主要為大家分享了最有價(jià)值的三道關(guān)于JVM的面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,感興趣的小伙伴們可以參考一下
    2021-08-08
  • Java中的內(nèi)存泄漏

    Java中的內(nèi)存泄漏

    這篇文章主要介紹了Java中的內(nèi)存泄漏的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)Java,感興趣的朋友可以了解下
    2020-11-11
  • Java中使用patchca生成超炫的驗(yàn)證碼

    Java中使用patchca生成超炫的驗(yàn)證碼

    這篇文章主要介紹了Java中使用patchca生成超炫的驗(yàn)證碼 的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • JDBC之PreparedStatement類中預(yù)編譯的綜合應(yīng)用解析

    JDBC之PreparedStatement類中預(yù)編譯的綜合應(yīng)用解析

    SQL 語句被預(yù)編譯并存儲在 PreparedStatement 對象中。然后可以使用此對象多次高效地執(zhí)行該語句
    2013-07-07
  • spring/springboot整合dubbo詳細(xì)教程

    spring/springboot整合dubbo詳細(xì)教程

    今天教大家如何使用spring/springboot整合dubbo,文中有非常詳細(xì)的圖文介紹及代碼示例,對正在學(xué)習(xí)java的小伙伴有很好地幫助,需要的朋友可以參考下
    2021-05-05
  • Java利用配置重試策略解決超時(shí)問題

    Java利用配置重試策略解決超時(shí)問題

    在web應(yīng)用中,由于網(wǎng)絡(luò)原因或其他不可預(yù)測的原因,應(yīng)用間會出現(xiàn)調(diào)用失敗的情形,通過配置重試策略可以有效解決外在原因?qū)е碌南到y(tǒng)故障。本文就來詳細(xì)說說如何利用配置重試策略解決超時(shí)問題
    2022-10-10
  • Java中Easyexcel?實(shí)現(xiàn)批量插入圖片功能

    Java中Easyexcel?實(shí)現(xiàn)批量插入圖片功能

    這篇文章主要介紹了Easyexcel?實(shí)現(xiàn)批量插入圖片,本文通過實(shí)例代碼給大家介紹了easyexcel文檔處理工具、自定義圖片處理器的相關(guān)知識,需要的朋友可以參考下
    2022-04-04

最新評論

长沙市| 双桥区| 宁陵县| 新民市| 连平县| 塘沽区| 江津市| 博白县| 青岛市| 东源县| 石狮市| 神农架林区| 巍山| 中阳县| 白银市| 伽师县| 内乡县| 泰州市| 类乌齐县| 丹寨县| 武穴市| 盖州市| 砚山县| 老河口市| 星座| 灵川县| 定结县| 瓦房店市| 义马市| 会理县| 吐鲁番市| 新巴尔虎右旗| 青龙| 昌图县| 岳西县| 上饶县| 遵义县| 拜城县| 曲麻莱县| 锡林浩特市| 宜昌市|