第六章 類檔案結構
第六章 類檔案結構
實現平臺無關性的基礎是虛擬機器和位元組碼的儲存格式。Java虛擬機器不與任何程式語言繫結,只和其Class
檔案這種特殊的二進位制檔案格式關聯。
6.1 Class類檔案結構
Class檔案格式採用類似C結構體的偽結構儲存,包含兩種數:無符號數和表。
- 無符號數:基本資料型別 , u1,u2,u3,u4表示不同的長度
- 表:多個無符號數或其他的表作為資料相複合成的複合資料型別。習慣info結尾
1 魔數和Class檔案版本
- 頭4個位元組成為魔數。用來確定檔案能否被虛擬機器載入
- 緊接著4個位元組是Class檔案版本號,5和6位元組是次版本號。7和8是主版本號(大版本+1)。
2 常量池
主次版本之後是常量池入口,
常量池主要存放兩大類變數:
- 字面量:類似常量概念,比如字串和宣告為final的常量值。
- 符號引用:屬於編譯原理的概念
- 被模組匯出或開放的包
- 類和介面的全限定名
- 方法的名稱和描述符
- 方法控制代碼、方法型別
- 動態呼叫點和動態常量
實際上,Java是在虛擬機器載入Class檔案時才進行動態連線。
虛擬機器載入類時,會從常量池中獲取對應的符號引用,再在類建立或執行時解析、翻譯到具體的記憶體中。(這部分涉及到虛擬機器的類載入機制)
Tips:
-
而常量池中,會存在每種基本型別對應的字面量。這個也就是為什麼會存在對應的基本資料型別??
-
Class檔案中的方法,欄位都需要引用
CONSTANT_UTF_8
-
CONSTANT_Class_info 包含tag和name_index ,tag時標誌位,index是常量索引,指向哪個常量結構例項。
3 訪問標誌
常量池之後,緊接著的2個位元組代表訪問標誌。
包括:是類還是介面、是否定義為public型別、是否定義為abstract、具體是類的話,是否被宣告為final 等等
4 類索引、父類索引與介面索引集合
類索引和父類索引,都是u2型別的資料庫。介面索引集合是u2的集合
5 欄位表集合
欄位表用於描述介面或者類中宣告的變數。 但不包含在方法內宣告的區域性變數。
方法表,屬性表
方法表 包括訪問標誌,名稱索引,描述符索引,屬性表集合。(訪問標識就包括synchronized,abstract等關鍵字)
......
6.2 位元組碼指令
同步指令
JVM支援方法級的同步和方法內部程式碼塊的同步,這兩種都是使用管程(Monitor,或者稱為鎖)來實現的。
方法級同步:
隱式,無需位元組碼指令控制。實現通過方法表中的ACC_SYNCHRONIZED訪問標識瞭解是否是同步方法。
此時執行緒執行到這裡就會先持有鎖,然後再執行方法,執行完成後再釋放。
語句塊同步:
minitorener
和monitorexit
兩條指令支援synchronized關鍵字的語義。
others: 為了保證在方法異常完成時monitorenter
和monitorexit
指令依然可以正確配對執行,編譯器會產生一個異常處理程式,這個宣告可以處理所有的異常,其目的就是保證monitorexit
的指令的執行。