最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

Java類加載機制,你了解嗎?

2020-12-26 13:38 作者:編程大戰(zhàn)  | 我要投稿

1、類的加載

類的加載是指將類的.class文件讀取進內(nèi)存中,并將其放在JVM運行時數(shù)據(jù)區(qū)的方法區(qū)內(nèi),然后在堆中創(chuàng)建一個java.lang.Class對象,用于封裝類在方法區(qū)中的數(shù)據(jù)結(jié)構(gòu),同時作為方法區(qū)數(shù)據(jù)的訪問入口。

2、類的生命周期

類的生命周期指一個class文件從加載到卸載的整個過程

3、類的加載過程

JVM將類的加載分為三個階段:裝載(Load)鏈接(Link)、初始化(Initialize)

3.1 裝載:查找并加載類的二進制數(shù)據(jù)

在硬盤上查找并通過IO讀入字節(jié)碼文件,使用到類時才會加載,例如調(diào)用類的main()方法,new對象等等,在加載階段會在內(nèi)存中生成一個代表這個類的Java.lang.Class對象,作為方法區(qū)這個類的各種數(shù)據(jù)的訪問入口。

3.2 鏈接:驗證、準(zhǔn)備、解析

  • 驗證
    校驗字節(jié)碼文件的正確性、安全性,包括四種驗證:文件格式驗證、元數(shù)據(jù)的驗證、字節(jié)碼驗證、符號引用驗證

  • 準(zhǔn)備
    為類變量(static修飾的字段變量)分配內(nèi)存并且設(shè)置該類變量的初始值,這里不包含final修飾的static,因為final在編譯的時候就已經(jīng)分配了。也不會為實例變量分配初始化,實例變量會隨著對象分配到堆內(nèi)存中。

  • 解析
    把常量池中的符號引用轉(zhuǎn)換為直接引用,靜態(tài)鏈接過程

3.3 初始化:初始化靜態(tài)變量,執(zhí)行靜態(tài)代碼塊

3.3.1 類的初始化時機

如果一個類被直接引用,就會觸發(fā)類的初始化。在Java中,直接引用的情況有:

  • 通過new關(guān)鍵字實例化對象、讀取或設(shè)置類的靜態(tài)變量、調(diào)用類的靜態(tài)方法

  • 通過反射執(zhí)行以上三種行為

  • 初始化子類的時候,會觸發(fā)父類的初始化

  • 作為程序的入口直接運行時(main方法)

3.3.2 類初始化步驟

  • 假如這個類還沒有被加載和鏈接,則程序先加載并連接該類(動態(tài)加載:主類在運行過程中如果使用到其他類,會逐步加載這些類 eg:jar包和war包中的類并不是一次性都加載到內(nèi)存中,而是使用時才加載)

  • 假如該類的直接父類還沒有被初始化,則先初始化其直接父類

  • 假如類中有初始化語句,則系統(tǒng)依次執(zhí)行這些初始化語句

4、類加載后方法區(qū)存儲內(nèi)容

類被加載到方法區(qū)中后主要包含運行時常量池、類型信息、字段信息、方法信息、類加載器的引用、對應(yīng)class實例的引用等信息。

類加載器的引用:這個類到類加載器實例的引用

對應(yīng)class實例的引用:類加載器在加載類信息放到方法區(qū)中后,會創(chuàng)建一個對應(yīng)的Class 類型的對象實例放到堆(Heap)中, 作為開發(fā)人員訪問方法區(qū)中類定義的入口和切入點。

5、類加載器

類加載過程主要通過類加載器實現(xiàn),Java中有以下幾種類加載器:

  • 引導(dǎo)類加載器(Bootstrap ClassLoader)
    負(fù)責(zé)加載支撐JVM運行的位于JRE的lib目錄下的核心類庫,比如rt.jar\charsets.jar等,由C++實現(xiàn),不是ClassLoader子類,Java程序無法直接引用。

  • 拓展類加載器(Extension ClassLoader)
    負(fù)責(zé)加載支撐JVM運行的位于JRE的lib目錄下的ext拓展目錄中的類庫

  • 應(yīng)用類加載器(App ClassLoader)
    負(fù)責(zé)加載ClassPath路徑下的類包,主要加載開發(fā)人員寫的類

  • 自定義類加載器(Custom ClassLoader)
    負(fù)責(zé)加載用戶自定義路徑下的類包

類加載器之間存在父子層級結(jié)構(gòu):

6、雙親委派機制

6.1 定義

雙親委派機制是指當(dāng)一個類加載器收到一個類加載請求時,該類加載器首先會把請求委派給父類加載器。每個類加載器都是如此,只有在父類加載器在自己的加載路徑下找不到指定類時,子類才會嘗試自己去加載。

6.2 工作過程

  1. 當(dāng)應(yīng)用程序類加載器收到一個類加載請求時,他首先不會自己去嘗試加載這個類,而是將這個請求委派給父類加載器Extension ClassLoader去完成。

  2. 當(dāng)Extension ClassLoader收到一個類加載請求時,他首先也不會自己去嘗試加載這個類,而是將請求委派給父類加載器Bootstrap ClassLoader去完成。

  3. 如果Bootstrap ClassLoader加載失敗(在<JAVA_HOME>\lib中未找到所需類),就會讓Extension ClassLoader嘗試加載。

  4. 如果Extension ClassLoader也加載失敗,就會使用Application ClassLoader加載。

  5. 如果Application ClassLoader也加載失敗,就會使用自定義加載器去嘗試加載。

  6. 如果均加載失敗,就會拋出ClassNotFoundException異常。

6.3 雙親委托機制實現(xiàn)源碼(JDK 1.8)

6.4 雙親委托作用

  1. 沙箱安全機制:防止核心類庫被篡改,自己寫的java.lang.String不會被加載。

  2. 避免類的重復(fù)加載:當(dāng)父加載器已經(jīng)加載過該類時,子加載器就沒必要重新加載一次,保證被加載類的唯一性。

7、自定義類加載器

8、如何打破雙親委派機制

核心:繼承ClassLoader,重寫類加載方法,實現(xiàn)加載邏輯,不委托給雙親加載





Java類加載機制,你了解嗎?的評論 (共 條)

分享到微博請遵守國家法律
奉节县| 潼南县| 临邑县| 海盐县| 弥渡县| 盐亭县| 桂阳县| 临颍县| 六安市| 清丰县| 海安县| 沭阳县| 栖霞市| 双牌县| 铜山县| 射阳县| 铜陵市| 洛宁县| 阳泉市| 瓮安县| 青岛市| 玉林市| 古蔺县| 六枝特区| 榆中县| 新安县| 新兴县| 通榆县| 壤塘县| 维西| 岐山县| 六安市| 石城县| 达拉特旗| 奉贤区| 石林| 简阳市| 荣昌县| 临湘市| 聂拉木县| 元氏县|