1. 程式人生 > >虛擬機器系列 | JVM類載入機制

虛擬機器系列 | JVM類載入機制

本文原始碼:[GitHub·點這裡](https://github.com/cicadasmile/java-base-parent) || [GitEE·點這裡](https://gitee.com/cicadasmile/java-base-parent) # 一、類載入簡介 類的載入機制是指把編譯後的.class類檔案的二進位制資料讀取到記憶體中,併為之建立一個java.lang.Class物件,用來封裝類在元資料空間的資料結構。 ![](https://img2020.cnblogs.com/blog/1691717/202009/1691717-20200922112534870-545901769.png) 類在JVM中的生命週期為:載入,連線,初始化,使用,解除安裝。不過這裡只重點描述載入,連線,初始化這三個過程。 # 二、載入過程 基於一張圖看類載入子系統的細節流程: ![](https://img2020.cnblogs.com/blog/1691717/202009/1691717-20200922112922107-300511113.png) ## 1、載入階段 **過程描述** 載入階段需要完成以下三個過程: - 通過類的全限定名來獲取其定義的二進位制位元組流; - 將位元組流所代表的靜態儲存結構轉化為雲資料空間的執行時資料結構; - 在堆Heap中生成一個代表這個類的java.lang.Class物件,作為對元資料空間中這些資料的訪問入口; **類載入器** - 引導類載入器 Bootstrap-ClassLoader基於C/C++實現,負責載入Java的核心類庫JAVA_HOME\jre\lib\rt.jar,該載入器不繼承自ClassLoader抽象類,並且只加載包名為java、javax、sun等開頭類,一次保證對核心原始碼的保護。 - 擴充套件類載入器 Extension-ClassLoader,基於Java語言,由sun.misc.Launcher$ExtClassLoader實現,派生於ClassLoader抽象類,從java.ext.dirs系統變數指定的路徑中的載入類庫,或者JDK安裝目錄jre\lib\ext目錄下載入。 - 系統類載入器 Application-ClassLoader,基於Java語言,由sun.misc.Launcher$ExtClassLoader實現,它負責載入環境變數ClassPath指定的類庫,如果在應用程式中沒有自定義類載入器,一般情況下作為程式中預設的類載入器。 ## 2、連線階段 **驗證** 目的在於確保Class檔案的位元組流中包含的資訊符合當前虛擬機器的要求,保證載入類的正確性,不會危害虛擬機器自身的安全,主要包括四種檢驗動作: - 檔案格式驗證:驗證位元組流是否符合Class檔案格式的規範; - 元資料驗證:確保其描述的資訊符合Java語言規範的要求; - 位元組碼驗證:確定程式語義是符合邏輯的; - 符號引用驗證:確保解析動作能正確執行。 **準備** 為類的靜態變數分配記憶體,並初始化為預設值,這時候進行記憶體分配的僅包括類變數(static)修飾,不包括(final-static)修飾的,這裡也不會為例項變數分配初始化,例項變數會隨著物件一塊分配到Java堆中。 **解析** 將常量池中的符號引用轉換為直接引用的過程,直接引用就是直接指向目標的指標、相對偏移量或一個間接定位到目標的控制代碼。解析主要針對類或介面、欄位、類方法、介面方法、方法型別等,解析的動作實際是會隨著JVM在執行完初始化之後再執行的。 ## 3、初始化階段 執行類構造器clinit()方法的過程,該方法不需要自定義,是javac編譯器自動收集類中的所有類變數的賦值動作和靜態程式碼塊中的語句合併而來,Jvm要保證clinit()方法在多執行緒訪問下的安全性。 # 三、機制策略 ## 1、雙親委派模式 ![](https://img2020.cnblogs.com/blog/1691717/202009/1691717-20200922112936894-1474509133.png) 類載入器收到了類載入的請求時,不會自己先去嘗試載入這個類,而是把請求委託給父載入器去執行; 如果父載入器還存在父類載入器,則依次向上委託,因此類載入請求最終都應該被傳遞到頂層的啟動類載入器中; 如果父類載入器可以完成類載入請求,就直接成功返回,只有當父載入器在無法完成該載入,子載入器才會嘗試自己去載入該類; ## 2、沙箱安全機制 假設自定義一個類名為String且所在包為java.lang,在使用引導類載入器載入時會先載入JDK中的String類,因為這個類本來是屬於jdk的,後面再次出現String類就會報錯,以此保證原始碼不被惡意篡改,這就是沙箱安全機制。 # 四、原始碼地址 ``` GitHub·地址 https://github.com/cicadasmile/java-base-parent GitEE·地址 https://gitee.com/cicadasmile/java-base-parent ``` **推薦閱讀:程式設計體系整理** |序號|專案名稱|GitHub地址|GitEE地址|推薦指數| |:---|:---|:---|:---|:---| |01|Java描述設計模式,演算法,資料結構|[GitHub·點這裡](https://github.com/cicadasmile/model-arithmetic-parent)|[GitEE·點這裡](https://gitee.com/cicadasmile/model-arithmetic-parent)|☆☆☆☆☆| |02|Java基礎、併發、面向物件、Web開發|[GitHub·點這裡](https://github.com/cicadasmile/java-base-parent)|[GitEE·點這裡](https://gitee.com/cicadasmile/java-base-parent)|☆☆☆☆| |03|SpringCloud微服務基礎元件案例詳解|[GitHub·點這裡](https://github.com/cicadasmile/spring-cloud-base)|[GitEE·點這裡](https://gitee.com/cicadasmile/spring-cloud-base)|☆☆☆| |04|SpringCloud微服務架構實戰綜合案例|[GitHub·點這裡](https://github.com/cicadasmile/husky-spring-cloud)|[GitEE·點這裡](https://gitee.com/cicadasmile/husky-spring-cloud)|☆☆☆☆☆| |05|SpringBoot框架基礎應用入門到進階|[GitHub·點這裡](https://github.com/cicadasmile/spring-boot-base)|[GitEE·點這裡](https://gitee.com/cicadasmile/spring-boot-base)|☆☆☆☆| |06|SpringBoot框架整合開發常用中介軟體|[GitHub·點這裡](https://github.com/cicadasmile/middle-ware-parent)|[GitEE·點這裡](https://gitee.com/cicadasmile/middle-ware-parent)|☆☆☆☆☆| |07|資料管理、分散式、架構設計基礎案例|[GitHub·點這裡](https://github.com/cicadasmile/data-manage-parent)|[GitEE·點這裡](https://gitee.com/cicadasmile/data-manage-parent)|☆☆☆☆☆| |08|大資料系列、儲存、元件、計算等框架|[GitHub·點這裡](https://github.com/cicadasmile/big-data-parent)|[GitEE·點這裡](https://gitee.com/cicadasmile/big-data-parent)|☆☆☆