JVM學習筆記之類裝載器-ClassLoader

JVM學習筆記之類裝載器-ClassLoader

本文字數:2300,閱讀耗時7分鐘

JVM體系結構概覽

 

類裝載器ClassLoader:

負責加載class文件,class文件在文件開頭有特定的文件標識,將class文件字節碼內容加載到內存中,並將這些內容轉換成方法區中的運行時數據結構並且ClassLoader只負責class文件的加載,至於class文件是否可以允許,則由Execution Engine決定。

本文是由凱哥Java(WXID:kaigejava)分享《JVM系列教程》

 

我們來看看Java類編譯成class文件後,文件開頭特定的文件標識是什麼樣的?如下圖:

 

類加載器

類加載器的分類:

JVM自帶的三個類加載器

啓動類加載器:Bootstrap 使用C++語言寫的

擴展類加載器:Extension 使用Java語言寫的

應用程序類加載器:AppclassLoader。Java也叫系統類加載器,加載當前引用的classPath所有類。

用戶自定義加載器:

需要繼承Java.lang.ClassLoader的子類。

幾種類加載器關係如下圖:

 

代碼演示:

一:啓動類加載器--查看Object的類加載器

執行:

Object obj = new Object();

System.out.println("obj classLoader:"+obj.getClass().getClassLoader());

執行後,我們發現obj的類加載器是null .如下圖:

 

分析原因:Object是所有類的父類。是頂級對象。因爲是頂級的,所有object的類加載器使用的是bootstrap類加載器。也即調用的是最底層的,所以就是null.

二:查看自定義類的類加載器

自定義一個類:MyObject輸出該類的classloader:

sun.misc.Launcher$AppClassLoader.如下圖:

 

我們可以看到,自定義類的類加載器來自於AppClassLoader.也即是應用服類加載器。

思考:

爲什麼我們安裝jdk之後,就可以直接使用string類、list類等這些類呢?這些類是什麼時候被加載進去的呢?

代開jdk安裝目錄,找到jre,然後再lib文件夾下找到rt.jar.這個jar就是Java運行時需要的。解壓後,我們找到java.lang.string:

 

 

現在知道爲什麼,安裝jdk之後,我們就可以直接使用很多類了吧。因爲這些類所在的jar再啓動的時候,就被bootstap啓動類加載器加載了,所以我們就可以直接使用了!!

怎麼證明rt.jar被加載的呢?

我們從自定義的類加載器:sun.misc.Launcher$AppClassLoader。根據包名插在Launcher類所在的位置:

 

我們是在rt.jar中的sun\misc包下找到的。

說明:launcher是一個Java虛擬機的入口應用

三:擴展類加載器

擴展類加載器時什麼?怎麼用?

根據名字,我們就可以知道,該加載器是爲了擴展Java功能的,不被淘汰的。在Java的API中,我們會看到很多,javax.xxx的。這些javax包下的類就是擴展類加載器管理的。

 

對應jre中的ext文件夾下:

 

四:自定義類加載器的層級關係:

下面代碼執行後的結果是什麼?

private static void showMyObjectClassLoaderLeve() {

MyObject myObject = new MyObject();

System.out.println("MyObject 的爺爺:"+myObject.getClass().getClassLoader().getParent().getParent());

System.out.println("MyObject 的爸爸:"+myObject.getClass().getClassLoader().getParent());

System.out.println("MyObject 自己的:"+myObject.getClass().getClassLoader());

}

 

從運行結果中我們可以看到:

自定義類的類加載器是:AppClassLoader

其父加載器:ExtclassLoader

其父加載器的父加載器:null

從這個層級關係中,我們就可以知道,原來我們自己寫的類是在擴展類加載器下。

思考:

如果是object.getclass().getClassLoader().getParent()會輸出什麼?

答案是:會拋出空指針異常。爲什麼呢?因爲Object是jvm自帶的。沒有父加載器了。

五:用戶自定義的類加載器

需要繼承Java.lang.ClassLoader這個類,然後在自定義處理。

如何更好的理解JVM的幾種類加載器呢?

我們生活在地球上,其中空氣、水、陽光這些是我們必須且賴以生存的基本條件,這三個就相當於是JVM的啓動類加載器(BootStap加載器);

爲了能安全的生存下去,抵擋自然界或是外界威脅,我們組成了團體,最後組成國家,有了國家的軍隊保護着就安全了。這就相當於是擴展類加載器(Externsion Class Loader)

要想成爲中國人,擁有中國國籍的話,需要至少父母一方是中國人(其他特殊情況不考慮),這個就相當於是應用程序類加載器(AppClassLoader)了;

如果想要生活的更好,自己就要努力,就要有個好工作,有一套屬於自己的房子。這個就相當於是用戶自定義的類加載器了。

簡圖如下:

接下來學習:Java的雙親委派機制及沙箱安全機制是什麼?如何理解jvm的雙親委派機制?用代碼如何驗證?歡迎大家和凱哥Java(WXID:kaigejava)一起繼續學習

 

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