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

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

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

JVM體系結構概覽安全

0ixkSbWJTPs


類裝載器ClassLoader:

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

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

0ixkSbv5sp6


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

0ixkScFYBtY


類加載器學習

類加載器的分類:

JVM自帶的三個類加載器spa

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

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

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

用戶自定義加載器:

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

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

0ixkSeYkBrE


代碼演示:

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

執行:

Object obj = new Object();

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

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

0ixkSetgewq


分析緣由:Object是全部類的父類。是頂級對象。由於是頂級的,全部object的類加載器使用的是bootstrap類加載器。也即調用的是最底層的,因此就是null.

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

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

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

0ixkSfL35ZQ


咱們能夠看到,自定義類的類加載器來自於AppClassLoader.也便是應用服類加載器。

思考:

爲何咱們安裝jdk以後,就能夠直接使用string類、list類等這些類呢?這些類是何時被加載進去的呢?

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

0ixkSfcNjMm


0ixkSfwcWGG


如今知道爲何,安裝jdk以後,咱們就能夠直接使用不少類了吧。由於這些類所在的jar再啓動的時候,就被bootstap啓動類加載器加載了,因此咱們就能夠直接使用了!!

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

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

0ixkSgBMz2G


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

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

三:擴展類加載器

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

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

0ixkSgTuSvo


對應jre中的ext文件夾下:

0ixkSgllBtA


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

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

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());

}

0ixkShU3PGK


從運行結果中咱們能夠看到:

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

其父加載器:ExtclassLoader

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

從這個層級關係中,咱們就能夠知道,原來咱們本身寫的類是在擴展類加載器下。

思考:

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

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

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

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

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

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

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

要想成爲中國人,擁有中國國籍的話,須要至少父母一方是中國人(其餘特殊狀況不考慮),這個就至關因而應用程序類加載器(AppClassLoader)了;

若是想要生活的更好,本身就要努力,就要有個好工做,有一套屬於本身的房子。這個就至關因而用戶自定義的類加載器了。

簡圖以下:

0ixkShof9Zg


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

0ixlzTU21ia

相關文章
相關標籤/搜索