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)一起繼續學習