Java虛擬機器——類檔案結構

怪盜基德007發表於2020-10-04

一、Class檔案結構

Class檔案是一組以8個位元組為基礎單位的二進位制流,各個資料專案嚴格按照順序緊湊地排列在檔案中,中間沒有任何分隔符。根據《java虛擬機器規範》的規定,class檔案格式採用一種類似於C語言結構體的偽結構來儲存資料。偽結構中只有兩種資料型別:無符號數和表。

  • 無符號數屬於基本資料型別,以u1、u2、u4、u8來分別代表1、2、4、8個位元組的無符號數。
  • 表由多個無符號數或其他表作為資料項構成的複合資料型別。整個class檔案本質上也可以視為一張表。

class檔案具體內容包含魔數、版本號、常量池、訪問標誌、索引集合、欄位表集合、方法表集合、屬性表集合等資料。

魔數是class檔案的頭4個位元組,它唯一的作用是確定這個檔案是否是一個能夠被虛擬機器接受的class檔案。class檔案的魔數固定為0xCAFEBABE。

常量池相當於class檔案的資源倉庫,主要存放字面量和符號引用。

由於class檔案中方法、欄位等都需要引用CONSTANT_Utf8_info型常量來描述名稱,所以CONSTANT_Utf8_info型常量的最大長度也就是Java中方法、欄位名的最大長度,即u2型別最大值65535。所以Java中超過64KB英文字元的變數或方法名是無法編譯的。

二、位元組碼指令

java虛擬機器支援方法級的同步和方法內部一段指令序列的同步,這兩種同步結構都使用管程(Monitor,即通常所說的“鎖”)來實現。

方法級的同步是隱式的,不需要通過位元組碼指令控制,它實現在方法呼叫和返回操作之中。虛擬機器可以從方法常量池中的方法表結構中的ACC_SYNCHRONIZED訪問標誌得知一個方法是否被宣告為同步方法。呼叫方法時,呼叫指令檢查方法的ACC_SYNCHRONIZED訪問標誌是否被設定,如果設定了,執行執行緒就要求先成功持有管程,然後才能執行方法,最後方法完成時釋放管程。如果方法執行時遇到異常,且在方法內部無法處理,那這個同步方法所持有的管程將在異常拋到同步方法邊界之外時自動釋放。

同步一段指令集序列由synchronized語句塊表示,java虛擬機器指令集中有monitorenter和monitorexit兩條指令來支援synchronized關鍵字的語義。

相關文章