轉 JVM載入Class檔案的原理機制
阿新 • • 發佈:2019-01-24
1.java中的所以類,必須被載入到JVM中才能執行,這個載入是由類載入器完成的,類載入器所做的工作實質上是把類檔案從硬碟讀取到記憶體中
2.java中的類大致分為三種:
1、系統類
2、擴充套件類
3、程式設計師自定義的類
3.類載入的方式,兩種
1、隱式裝載,程式在執行過程中碰到new等方式生成物件時,隱式呼叫類載入器載入對應的類到JVM中
2,顯示裝載,通過class.forName()等方法,顯示載入需要的類
4.類載入的動態性體現
一個應用程式總是由n多個類組成,java程式啟動時,並不是一次性把全部的類載入後在執行的,它總是先把保證執行的基礎類一次性載入到JVM中,其他的類等到JVM用到的時候再載入,這樣節約記憶體開銷,
5.java類裝載器
java中的類裝載器把類載入JVM中,值得注意的是JVM的類裝載器有3個
Bootstrap ClassLoader - 負責載入系統類
|
--ExtClassLoader - 負責載入擴充套件類
|
-- AppClassLoader 負責載入應用類
三個類載入器一方面各自負責各自的區塊,另一方方面實現委託模型
6.類載入器之間是如何協調工作的
碰到一個類需要載入時,java採用了委託模型機制,這個機制簡單來講,就是類裝載器有載入類的需求時,會先請示器parent使用其搜尋路徑幫忙載入,如果parent找不到,那麼才會自己依照自己的搜尋路徑搜尋類。
下面舉一個例子來說明,為了更好的理解,先弄清楚幾行程式碼:
public class Test{
public static voidmain(String[] arg){
ClassLoader c = Test.class.getClassLoader(); //獲取Test類的類載入器
System.out.println(c);
ClassLoader c1 = c.getParent(); //獲取c這個類載入器的父類載入器
System.out.println(c1);
ClassLoader c2 = c1.getParent();//獲取c1這個類載入器的父類載入器
System.out.println(c2);
}
}
執行結果:
[email protected]
[email protected]
null
可以看出Test是由AppClassLoader載入器載入的
AppClassLoader的Parent 載入器是 ExtClassLoader但是ExtClassLoader的Parent為 null 是怎麼回事呵,如果留意的話,前面有提到BootstrapLoader是用C++語言寫的,依java的觀點來看,邏輯上並不存在BootstrapLoader的類實體,所以在java程式程式碼裡試圖打印出其內容時,我們就會看到輸出為null。
類載入器ClassLoader(抽象類)描述JVM載入class檔案的原理機制
類裝載器就是尋找類或介面位元組碼檔案進行解析並構造JVM內部物件表示的元件,
裝載類到JVM的步驟
1、裝載:查詢和匯入class檔案
2、連線:其中解析步驟是可選的
1)檢查:檢查載入的class檔案資料的正確性
2)準備:給類的靜態變數分配儲存空間
3)解析:將符號引用轉換成直接引用
3、初始化:對靜態變數,靜態程式碼塊執行初始化
java裝載類使用“全盤負責委託機制”:
是指一個ClassLoader裝載一個類時,除非顯示使用另一個ClassLoader,該類所依賴及引用的類也由這個ClassLoader載入。
“委託機制”是指先委託父類裝載器尋找目標類,只有在找不到的情況下才從自己的路徑中查詢並載入。這一點是從安全的方面考慮的,試想一下如果有人寫了一個惡意的基礎類(如java.lang.String)並載入到JVM將引起嚴重後果,但是全盤負責制,java.lang.String永遠是由根裝載器來裝載的,避免以上情況發生。