1. 程式人生 > 實用技巧 >Java的虛擬機器(JVM)的類載入子系統的解析過程 - Break易站

Java的虛擬機器(JVM)的類載入子系統的解析過程 - Break易站

[

類載入子系統是JVM裡面的一個重要的環節。與C/C++那些需要在編譯器期進行連線工作的語言不同,Java類的載入、連線和初始化都是在程式執行時完成的,只有在類被需要的時候才進行動態載入。

1)JVM何時載入類?


有且只有以下5種情況:

  • 建立新物件(new)、設定/讀取static欄位(putstatic/getstatic)或呼叫靜態方法(invokestatic)這四條指令時,如果該類沒有初始化,則初始化。
  • 使用java.lang.reflect包得方法進行反射呼叫的時候,如果該類沒有初始化,則初始化。
  • 當初始化一個類時,父類沒有初始化,則先初始化父類。
  • 當虛擬機器啟動,需要執行main()的主類,JVM首先初始化該類。
  • JDK 1.7的動態語言支援時,如果java.lang.invoke.MethodHandle例項最後的解析結果REF_getStatic、REF_putStatic、REF_invokeStatic的方法控制代碼,並且這個方法控制代碼所對應的類沒有進行過初始化,則初始化。

2)如何載入類?


類載入過程包括載入(Loading)、連結(Linking)和初始化(Initialization)三個過程。

載入(Loading)


  • 其中“根據全限定名獲取位元組流”的過程,可以有系統提供的類載入器完成,也可以由使用者自定義類載入器。
  • 對於HotSpot,Class物件雖然是物件,但仍然存放在方法區中。

連結-準備


  • 該階段值正式在方法區為類變數分配記憶體初始化類變數,
    public static int value = 123
    在準備階段初始化零值,而非123。初始化123的過程在初始化階段完成。

連結-解析


  • 將常量池中的符號引用替換成直接引用。其中對於非虛方法,在類載入階段就可以確定呼叫的版本,因此可以在此階段直接解析為直接引用;為對於虛方法(即支援多型),無法在此階段確定呼叫版本,虛方法的符號引用需等到程式執行到該符號引用的位元組碼時才能解析為直接引用。
  • 解析動作主要針對類或介面、欄位、類方法、介面方法、方法型別、方法型別等符號引用。
  • 執行讀寫欄位(getstatic、putstatic、getfield、putfield)、instanceof、方法呼叫(iinvokestatic、invokespecial、invokevirtual、invokedynamic)、new等操作符號引用的位元組碼之前,需要先進行符號引用解析。

初始化(Initialization)

  • 執行類構造器<clinit>:自動收集static變數和static{}塊,按原檔案出席西安的順序執行初始化。
  • <clinit>由編譯器自動生成,如果沒有static變數和static{}塊,就不會生成。

本文內容來自:Java的詳解:JVM的類載入子系統的解析過程 – Break易站

]
  •   本文標題:Java的虛擬機器(JVM)的類載入子系統的解析過程 - Break易站轉載請保留頁面地址:https://www.breakyizhan.com/javamianshiti/2837.html