1. 程式人生 > >轉 JVM載入Class檔案的原理機制

轉 JVM載入Class檔案的原理機制

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永遠是由根裝載器來裝載的,避免以上情況發生。