要點提煉| 理解JVM之類文件結構

之前還在美團實習的時候,當時讀《深入理解Java虛擬機》由于時間原因只總結了幾個章節,現在把余下的幾個章節補充上,發表順序有些混亂,章節主線詳見文章匯總|學習Android的一點一滴

本篇將介紹Class文件結構中的各個組成部分,以及每個部分的定義、數據結構和使用,有利于進一步了解虛擬機執行引擎。

  • 概述
  • 類文件結構
  • 字節碼指令

1.概述

運行在各種不同平臺上的虛擬機通過載入和執行同一種平臺無關的字節碼來實現了程序的“一次編寫,到處運行”。可見字節碼是構成平臺無關性的基石。

Java虛擬機不和Java等任何語言綁定,只和存儲字節碼的Class文件這種特定的二進制文件格式關聯,且并不關心Class的來源是何種語言,也體現了Java虛擬機的語言無關性


2.類文件結構

  • Class文件是一組以8位字節為基礎單位的二進制流,各個數據項目嚴格按照順序緊湊地排列在Class文件之中,中間無任何分隔符,當遇到需要占用8位字節以上空間的數據項時,會按照高位在前的方式分割成若干個8位字節進行存儲。
  • Class文件格式采用一種類似于C語言結構體的偽結構來存儲數據,包含兩種數據類型:
    • 無符號數:屬于基本數據類型;以u1、u2、u4、u8來分別代表1個字節、2個字節、4個字節和8個字節的無符號數;可用于描述數字、索引引用、數量值或按照UTF-8 編碼構成的字符串值。
    • :由多個無符號數或其他表作為數據項構成的復合數據類型;常以“_info”結尾;可用于描述有層次關系的復合結構的數據。
  • 整個Class文件本質上就是一張表,所包含的數據項如圖:

接下來依次介紹表中各個數據項的具體含義。

a. 魔數

  • 魔數(Magic Number):每個Class文件的頭4個字節
  • 作用:判斷該文件是否為一個能被虛擬機接受的Class文件

b.版本號

  • 版本號:包含主版本號和一系列次版本號
    • 次版本號(Minor Version):第5和第6個字節
    • 主版本號(Major Version):第7和第8個字節
  • 作用:判斷該文件是否在虛擬機處理的有效范圍內

c.常量池

  • 常量池:使用一個前置的容量計數器(constant_pool_count)加上若干個連續的常量項(constant_pool)來描述
    • 容量計數器:從1開始,目的是滿足后面某些指向常量池的索引值的數據在特定情況下需要表達“不引用任何一個常量池項目”的含義,這時可以把索引值置為0來表示
    • 常量項:如constant_pool_count=2表示常量池中有1個常量項
  • 特點:是Class文件的資源倉庫、是Class文件結構中與其他項目關聯最多的數據類型、是占用Class文件空間最大的數據項目之一、是在Class文件中第一個出現的表類型數據項目
  • 存放內容:兩大類常量
    • 字面量(Literal):指Java語言層面的常量概念,如文本字符串、聲明為final的常量值等
    • 符號引用(Symbolic References):指編譯原理方面的概念,包含類和接口的全限定名(Fully Qualified Name)、字段的名稱和描述符(Descriptor)、方法的名稱和描述符

Java代碼進行Javac編譯的過程同虛擬機加載Class文件的過程是動態連接的,因此在Class文件中不會保存各個方法、字段的最終內存布局信息,這就需要虛擬機在運行時從常量池獲得對應的符號引用,再在類創建時或運行時解析、翻譯到具體的內存地址之中。

d.訪問標志

  • 訪問標志(access_flags):常量池結束后兩個字節
  • 作用:識別一些類或者接口層次的訪問信息,包括該Class是類還是接口、是否定義為public類型、是否定義為abstract類型、若是類是否被聲明為final等。具體的標志位以及含義見圖:

e.類索引、父類索引與接口索引集合

  • 類索引(this_class)和父類索引(super_class)都是一個u2類型的數據、接口索引集合(interfaces)是一組u2類型的數據的集合
  • 作用: 通過這三項數據來確定這個類的繼承關系,具體的
    • 類索引:確定這個類的全限定名
    • 父類索引:確定這個類的父類的全限定名
    • 接口索引集合:描述這個類所實現的接口,并按照implements語句后的接口順序從左到右排列在接口索引集合中
      • 接口索引集合的入口第一項u2類型數據為接口計數器(interfaces_count),從0計數,如nterfaces_count=2表示該類實現了兩個接口

類全限定名:把類全名中的“.”都替換成“/”,為了使連續的多個全限定名之間不產生混淆,在使用時最后一般會加入一個“;”表示全限定名結束

f.字段表集合

  • 字段表(field_info):用于描述接口或者類中聲明的變量
  • 格式如圖
    • access_flags:存放字段的修飾符,具體的標志位以及含義見圖:
    • name_index:存放字段的簡單名稱,即沒有類型和參數修飾的字段名稱
    • descriptor_index:存放字段和方法的描述符,包括字段的數據類型、方法的參數列表(包括數量、類型以及順序)和返回值,具體的標志位以及含義見圖:
    • attribute_info:屬性表見后

g.方法表集合

  • 方法表(methods_info):用于描述接口或者類中聲明的方法
  • 格式如圖,可見和描述字段的方式非常類似,僅在訪問標志和屬性表集合的可選項中有所區別。

h.屬性表集合

  • 屬性表(attribute_info):用于描述某些場景專有的信息,在字段表、方法表等都攜帶自己的屬性表集合
  • 種類:


  • 結構:屬性名需要從常量池中引用一個CONSTANT_Utf8_info類型的常量來表示,屬性值是自定義的、需要通過一個u4的長度屬性說明屬性值所占用的位數

舉例class文件結構解析class文件屬性表解析


3.字節碼指令

  • 構成:由一個字節長度的表示某種特定操作含義的操作(操作碼、Opcode)和零至多個代表此操作所需的參數(操作數、Operands)構成
  • 特點:非完全獨立,即并非每種數據類型和每一種操作都有對應的指令,有些單獨的指令可以在必要的時候用來將一些不支持的類型轉換為可被支持的類型
  • 分類:將字節碼操作按用途大致分為9類
    • 加載和存儲指令:用于將數據在棧幀中的局部變量表和操作數棧之間來回傳輸
    • 運算指令:用于對兩個操作數棧上的值進行某種特定運算,并把結果重新存入到操作棧頂
    • 類型轉換指令 :用于實現用戶代碼中的顯式類型轉換操作,或者用于處理字節碼指令集中數據類型相關指令無法與數據類型一一對應的問題
    • 對象創建與訪問指令:用于對象創建,并通過對象訪問指令獲取對象實例或者數組實例中的字段或者數組元素
    • 操作數棧管理指令:用于直接操作操作數棧
    • 控制轉移指令:用于從指定的位置有條件或無條件地進行指令
    • 方法調用和返回指令:用于方法的調用,并根據返回值的類型去返回
    • 異常處理指令:用于檢測到異常狀況時自動拋出異常
    • 同步指令:用于方法內部一段指令序列的同步

具體指令見Java虛擬機字節碼指令簡介


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,156評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,401評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,069評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,873評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,635評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,128評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,203評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,365評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,881評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,733評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,935評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,475評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,172評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,582評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,821評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,595評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,908評論 2 372

推薦閱讀更多精彩內容