1. 程式人生 > 其它 >JVM類載入子系統(01)

JVM類載入子系統(01)

類載入子系統的作用

  1. 類載入子系統負責從檔案系統或者網路中載入class檔案,class檔案在檔案開頭有特定的檔案標識
  2. classLoader只負責class檔案的載入,execution engine負責是否可以執行
  3. 載入類的資訊存放在一塊方法區的記憶體空間。除了類的資訊,方法區中還會存放執行時常量池的資訊,可能還包括字串常量和數字常量(這部分常量資訊是class檔案中常量池部分的記憶體對映)

類載入器classLoader角色

  1. class file 存在本地硬碟上,可以理解為設計師畫在之上的模板,而最終這個模板在執行的時候是要載入到jvm當中來根據這個檔案例項化出n個例項
  2. class file載入到jvm中,被稱為dna元資料模板,放在方法區中
  3. 在class檔案-》jvm-》dna元資料模板,此過程就要一個運輸工具(類裝載器 class Loader)。

類的載入過程

  1. 載入(loading)
    1. 通過一個類的全限定名獲取此類的二進位制位元組流

    2. 將這個位元組流所代表的靜態儲存結構轉化為方法區的執行時資料結構

    3. 在記憶體中生成一個代表這個類的java.lang.class物件,作為方法區這個類的各種資料結構的訪問入口,反射(JVM為每個載入的`class`及`interface`建立了對應的`Class`例項來儲存`class`及`interface`的所有資訊;

      獲取一個`class`對應的`Class`例項後,就可以獲取該`class`的所有資訊;

      通過Class例項獲取`class`資訊的方法稱為反射(Reflection);

      JVM總是動態載入`class`,可以在執行期根據條件來控制載入class

  2. 連結(ln)
    1. 驗證:
      • 目的在於確保class檔案的位元組流中包含資訊符合當前虛擬機器要求,保證被載入類的正確性,不會危害虛擬機器的自生安全
      • 主要包括四種驗證,檔案格式驗證,元資料驗證,位元組碼驗證,符號引用驗證
    2. 準備:
      • 為類變數分配記憶體並設定該類變數的預設初始值,即零值
      • 這裡不包含用final修飾的static,因為final在編譯時就分配了,準備階段會顯式初始化
      • 這裡不會為例項變數分配初始化,類變數分配在方法區中,而例項變數是會隨著物件一起分配到java堆中
    3. 解析:
      • 將常量池內符號引用轉換為直接引用的過程
      • 事實上,解析操作往往會伴隨著jvm在執行完初始化之後再執行
      • 符號引用就是一組符號來描述所引用的目標直接引用就是直接指向目標的指標,相對偏移量或一個間接定位到目標的控制代碼
      • 解析動作主要針對類或介面,欄位,類方法,介面方法,方法型別等,對應常量池中的constant_class_info,constant_fieldref_info,constant_methodref_info等
  3. 初始化

    • 初始化階段就是執行類構造器方法()的過程
    • 此方法不需定義,是javac編譯器自動收集類中的所有類變數的賦值動作和靜態程式碼塊中的語句合併而來
    • 構造器方法中的指令按照語句在原始檔中出現的順序執行
    • ()不同於類的構造器(關聯:構造器是虛擬機器視角下的())
    • 若該類具有父類,jvm會保證子類的()執行前,父類的()已經執行完畢
    • 虛擬機器必須保證一個類的<.clinit>()方法在多執行緒下被同步加鎖