虛擬機中的類加載機制

前言

虛擬機把描述類的數據從Class文件加載到內存,並對數據進行校驗、轉換解析和初始化,最終形成可以被虛擬機直接使用的Java類型,這就是虛擬機的類加載機制。

類加載步驟

class文件通過類加載器加入到內存區域,類加載的過程是很複雜的,類的生命週期總共包括如下階段

  • 加載:在加載階段,JVM通過類的權限定名獲取字節流,然後將字節流展示的靜態存儲結構轉化爲方法區的運行時數據結構,然後在堆中生成類的Class對象
  • 鏈接
    • 驗證:驗證Class文件的格式,這是對JVM的一種保護
    • 準備:在這個階段會爲類變量分配內存以及設置初始值,當然Class對象在堆中,類變量也不例外,注意區分類變量和實例變量,這裏的初始值也是系統默認的初始值,指定的類屬性的值將會在初始化階段統一賦值,但是如果final修飾的基本類型或者String會立即賦值,因爲會被編譯器標記爲常量值。部分虛擬機還會構造與其他類層次相關的數據結構,比如用來實現虛方法的動態綁定的方法表,class文件被加載至虛擬機之前無法知道其他的類和方法,編譯時生成符號引用
    • 解析:class文件在加載到虛擬機之前無法知道其他類及方法、字段的具體地址,編譯時會通過符號引用代替他們。將引用符號解析成實際引用,如果符號引用指向未被加載的類,字段或者方法,那麼解析就會觸發加載。解析的執行過程是不固定的,他可以在初始化後解析,java語言支持的運行時綁定。
  • 初始化:編譯器自動收集類中所有的類變量以及靜態代碼塊產生類構造器<clinit>(),在初始化階段就會執行類構造器,對類屬性進行初始化,只有初始化過後的類纔是可執行狀態的,而JVM的類加載是按需加載,所以必定存在我們需要的類還未加載等,那麼那些情況會出發初始化甚至之前的階段呢?我在文末羅列了出來。
  • 使用 
  • 卸載

類加載器

class文件通過類加載器加載入內存,JVM中的類加載器採用雙親委派模型,Java虛擬機需要藉助類加載器查找字節流,類加載器:jVM中的類加載器採用雙親委派模型,其中啓動類加載器是基石,類的唯一性由類加載器實例以及類的全名確定,意思就是說同一個class文件經過不同的類加載器加載得到的兩個類也是不相同的。

啓動類加載器由C++實現,沒有對應對象,用null指代。其他的類加載器都是java.lang.ClassLoader的子 類,有對應java對象,這些類加載器需要其他的類加載器加載到虛擬機中

出了JVM中的類加載器,我們還可以定義自己的類加載器,執行特殊的加載(例如加密加載)。

類加載機制

  1. 雙親委派模型 當類加載器接收到請求時,先將請求轉發給父類加載器,父類沒有找到請求的類纔有子類加載
  2. Java9之前,啓動類加載器負責最基礎,最重要的類比如JRE的lib中的類(以及虛擬機參數-Xbootclasspath指定的類)
  3. 擴展類加載器是啓動類加載器的子類,負責相對次要,通用的類,比如JRE lib/ext中的類(以及系統變量java.ext.dirs指定的類)
  4. 應用類加載器是擴展類加載器的子類,負責加載應用程序路徑下的類,
  5. java 9 引入模塊系統,擴展類加載器更名爲平臺類加載器

 

發佈了37 篇原創文章 · 獲贊 40 · 訪問量 2923
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章