本文主要介紹了JVM載入一個類別的過程。具有很好的參考價值,以下跟著小編一起來看下吧
類別的載入過程
Java原始碼被編譯成class字節碼,JVM把描述類別資料的字節碼.Class檔案載入到內存,並對資料進行校驗、轉換解析和初始化,最終形成可以被虛擬機直接使用的java類型,這就是虛擬機器的類別載入機制。
類別從被載入到虛擬機器記憶體開始,到卸載出記憶體為止,它的生命週期包括了:載入(Loading)、驗證(Verification)、準備(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)、卸載(Unloading)七個階段,其中驗證、準備、解析三個部分統稱連結。
載入(裝載)、驗證、準備、初始化和卸載這五個階段順序是固定的,類別的載入過程必須按照這種順序開始,而解析階段不一定;它在某些情況下可以在初始化之後再開始,這是為了運行時動態綁定特性(也稱為動態綁定或晚期綁定,例如重寫)。
1.載入:
在載入階段,虛擬機器主要完成三件事:
1.透過一個類別的全限定名稱來取得定義此類的二進位位元組流。
2.將這個位元組流所代表的靜態儲存結構轉換為方法區域的執行時間資料結構。
3.在Java堆中產生一個代表這個類別的java.lang.Class對象,作為方法區域資料的存取入口
#相對於類別載入過程的其他階段,載入階段(準備地說,是載入階段中取得類別的二進位位元組流的動作)是開發期可控性最強的階段,因為載入階段可以使用系統提供的類別載入器(ClassLoader)來完成,也可以由使用者自訂的類別載入器完成,開發人員可以透過定義自己的類別載入器去控製位元組流的取得方式。
載入階段完成後,虛擬機器外部的二進位位元組流就按照虛擬機所需的格式儲存在方法區之中,方法區中的資料儲存格式有虛擬機實現自行定義,虛擬機並未規定此區域的具體資料結構。然後在java堆中實例化一個java.lang.Class類別的對象,這個物件作為程式存取方法區中的這些類型資料的外部介面。
2.驗證:
驗證階段作用是確保Class檔案的位元組流包含的資訊符合JVM規範,不會對JVM造成危害。如果驗證失敗,就會拋出一個java.lang.VerifyError異常或其子類別異常。驗證流程分為四個階段
1.檔案格式驗證:驗證位元組流檔案是否符合Class檔案格式的規範,並且能被目前虛擬機器正確的處理。
2.元資料驗證:是對字節碼所描述的資訊進行語意分析,以確保其所描述的資訊符合Java語言的規格。
3.字節碼驗證:主要是進行資料流和控制流的分析,保證被校驗類別的方法在執行時不會危害虛擬機。
4.符號引用驗證:符號參考驗證發生在虛擬機器將符號引用轉換為直接引用的時候,這個轉換動作將在解析階段中發生。
3.準備:
準備階段為變數分配記憶體並設定類別變數的初始化。在這個階段分配的僅為類別的變數(static修飾的變數),而不是包含類別的實例變數。對已非final的變量,JVM會將其設為“零值”,而不是其賦值語句的值:
pirvate static int size = 12;
#那麼在這個階段, size的值為0,而不是12。 final修飾的類別變數將會賦值成真實的值。
4.解析:
解析階段是虛擬機器常數池內的符號參考替換為直接引用的過程。
符號引用:符號引用是一組符號來描述所引用的目標對象,符號可以是任何形式的字面量,只要使用時能無歧義地定位到目標即可。符號引用與虛擬機器實現的記憶體佈局無關,引用的目標物件並不一定已經載入到記憶體中。
直接引用:直接引用可以是直接指向目標物件的指標、相對偏移量或是一個能間接定位到目標的句柄。直接引用是與虛擬機器記憶體佈局實現相關的,同一個符號引用在不同虛擬機器實例上翻譯出來的直接引用一般不會相同,如果有了直接引用,那引用的目標必定已經在記憶體中存在。
虛擬機器規格並沒有規定解析階段發生的具體時間,只要求了在執行anewarry、checkcast、getfield、instanceof、invokeinterface、invokespecial、invokestatic、invokevirtual、multianewarray、new、putfield和putstatic這13個用於操作符號所引用的字節碼指令之前,先將它們所使用的符號引用進行解析,所以虛擬機器實作會根據需要來判斷,到底是在類別被載入器載入時就對常數池中的符號引用進行解析,還是等到一個符號引用將要被使用前才去解析它。
解析的動作主要針對類別或介面、欄位、類別方法、介面方法四類符號引用進行。分別對應編譯後常數池內的CONSTANT_Class_Info、CONSTANT_Fieldref_Info、CONSTANT_Methodef_Info、CONSTANT_InterfaceMethoder_Info四種常數型別。
1.類別、介面的解析
#2.欄位解析
3.類別方法解析
#4.介面方法解析
#5.初始化:
類別的初始化階段是類別載入過程的最後一步,在準備階段,類別變數已賦過一次系統要求的初始值,而在初始化階段,則是根據程式設計師透過程式製定的主觀計畫去初始化類別變數和其他資源,或者可以從另一個角度來表達:初始化階段是執行類別構造器
6.使用:
新執行緒---程式計數器----jvm棧執行(物件參考)-----堆疊記憶體(直接引用)----方法區
7 .卸載:
GC垃圾回收
以上是JVM載入一個類別的過程的圖文詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!