深入理解JVM系列(一)類文件格式

本文介紹Java虛擬機的類文件格式。每個類文件都包含一個類或接口的定義没佑。雖然類或接口不需要有字面上包含在文件中的外部表示(例如,因為類是由類裝入器生成的),但我們口頭上將類或接口的任何有效表示稱為類文件格式笛洛。

java文件從編碼到執(zhí)行

image.png

1、首先我們有個x.java文件乃坤,通過javac命令編譯成x.class文件
2苛让、執(zhí)行java命令將x.class由ClassLoader加載到內(nèi)存里
3、通常我們在寫代碼的時候用到的java類庫也會被加載到內(nèi)存中
4湿诊、調(diào)用字節(jié)碼解釋器或JIT即時編譯器進行解釋或編譯
5狱杰、編譯完之后由執(zhí)行引擎通過os的硬件執(zhí)行

通常java都是使用解釋和編譯混合模式,非常常用的代碼就會由JIT(即時編譯器)編譯厅须,下次再執(zhí)行的時候就不要解釋器再一句一句的解釋執(zhí)行仿畸,效率會高很多,執(zhí)行引擎可以直接交給操作系統(tǒng)調(diào)用朗和,但是不是所有的代碼都由JIT編譯错沽,這樣就不能跨平臺了,所以java使用混合模式例隆。


image.png

JVM和語言無關

JVM和java并不是強綁定的甥捺,JVM只跟class格式的文件有關系,只要可以編譯出符合class規(guī)范的文件镀层,都可以在JVM上運行镰禾,所以JVM是定義了一種規(guī)范皿曲。目前可以運行在JVM上的語言有很多,比如Scala吴侦、groovy等等屋休。


image.png

類文件結構

類文件由單一的類文件結構組成:

ClassFile {
    u4             magic; 
    u2             minor_version;
    u2             major_version;
    u2             constant_pool_count;
    cp_info        constant_pool[constant_pool_count-1];
    u2             access_flags;
    u2             this_class;
    u2             super_class;
    u2             interfaces_count;
    u2             interfaces[interfaces_count];
    u2             fields_count;
    field_info     fields[fields_count];
    u2             methods_count;
    method_info    methods[methods_count];
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

類文件結構中的項如下:

  1. magic(魔數(shù))
    每個Java class 文件的前4個字節(jié)被稱為他的魔數(shù)(magic number):0x CAFEBABE 。魔數(shù)的作用在于备韧,可以輕松的分辨出java class文件和非java class 文件劫樟。如果一個文件不是以0xCAFEBABE 開頭的,那他肯定不是java class文件织堂。

  2. minor_version 和 major_version
    minor_version和major_version項的值是這個類文件的主版本號和次版本號叠艳。主版本號和次版本號一起決定類文件格式的版本。如果一個類文件的主版本號為M易阳,次版本號為M附较,則我們將其類文件格式的版本表示為M. M。因此潦俺,類文件格式的版本可以按字典順序排列拒课,例如,1.5 < 2.0 < 2.1事示。比如java8就是52.0其中major_version就是52早像,minor_version就是0。

  3. constant_pool.count 和 constant_pool
    class 文件中肖爵,魔數(shù)和版本號后面的是常量池卢鹦。constant_pool是一個結構表,它代表了各種字符串常量遏匆,類和接口名法挨,字段名谁榜,以及在類文件結構及其子結構中引用的其他常量幅聘。每個constant_pool表項的格式都由它的第一個“tag”字節(jié)表示。constant_pool表的索引從1到constant_pool_count - 1窃植。 常量池中的類型如下:

    入口類型 標志值 描述
    CONSTANT_Utf8 1 UTF-8 編碼的Unicode字符串
    CONSTANT_Integer 3 int類型字面值
    CONSTANT_Float 4 float 類型字面值
    CONSTANT_Long 5 long類型字面值
    CONSTANT_Double 6 double 類型字面值
    CONSTANT_Class 7 對一個類或接口的符號引用
    CONSTANT_String 8 string 類型字面值
    CONSTANT_Fieldref 9 對一個字段的符號引用
    CONSTANT_Methodref 10 對一個類中聲明的方法的符號引用
    CONSTANT_InterfaceMethodref 11 對一個接口中聲明的方法的符號引用
    CONSTANT_NameAndType 12 對一個字段或方法的部分符號引用
    CONSTANT_MethodHandle 15 方法句柄
    CONSTANT_MethodType 16 方法類型
    CONSTANT_InvokeDynamic 18 動態(tài)調(diào)用
  4. access_flags
    緊接常量池后面的兩個字節(jié)稱為 access_flags 帝蒿,access_flags項的值是一個標記的掩碼,用于表示該類或接口的訪問權限和屬性巷怜。下表規(guī)定了每個標志設置后的解釋葛超。

    標志名 設置后的含義 設置名
    ACC_PUBLIC 0x0001 public 類型 類和接口
    ACC_FINAL 0x0010 類為final類型 只有類
    ACC_SUPER 0x0020 使用新型的invokespecial語義 類和接口
    ACC_INTERFACE 0x0200 接口類型,不是類 類型 所有的接口延塑,沒有類
    ACC_ABSTRACT 0x0400 abstract類型 所有的接口绣张,部分類
  5. this_class
    接下來的兩個字節(jié)為this_class項,它是一個隊常量池的索引关带。this_class項的值必須是constant_pool表的有效索引侥涵。索引處的constant_pool條目必須是CONSTANT_Class_info結構,它表示這個類文件定義的類或接口。

  6. super_class
    在class文件中芜飘,緊接在this_class 之后的是 super_class 項务豺,它是一個兩個字節(jié)的常量池索引。對于一個類嗦明,super_class項的值必須為零或者必須是constant_pool表的有效索引笼沥。
    如果super_class項的值為非零,則該索引處的constant_pool項必須是CONSTANT_Class_info結構娶牌,它表示這個類文件定義的類的直接超類奔浅。無論是直接超類還是它的任何超類都不能在它的類文件結構的access_flags項中設置ACC_FINAL標志。
    如果super_class項的值為0诗良,那么這個類文件必須表示class對象乘凸,這是唯一沒有直接超類的類或接口。
    對于接口累榜,super_class項的值必須始終是constant_pool表的有效索引营勤。索引處的constant_pool條目必須是表示類對象的CONSTANT_Class_info結構。

  7. interfaces_count 和 intefaces
    緊接著 super_class 的是 interfaces_count壹罚。此項的含義為:在文件中該類直接實現(xiàn)或者由接口所擴展的父接口的數(shù)量葛作。在這個計數(shù)的后面,是名為 interfaces 的數(shù)組猖凛,它包含了對每個由該類或者接口直接實現(xiàn)的父接口的常量池索引赂蠢。

  8. fields_count 和 fields
    在class文件中,緊接在 interfaces 后面的是對在該類或者接口中所聲明的字段的描述辨泳。首先是名為 fields_count 的計數(shù)虱岂,它是類變量和實例變量的字段的數(shù)量總和。在這個計數(shù)后面的是不同長度的 field_info 表的序列菠红。只有在文件中由類或者接口聲明了的字段才能在 fields 列表中列出第岖。在 fields 列表中,不列出從超類或者父接口繼承而來的字段试溯。另一方面蔑滓,fields 列表可能會包含在對應的java源文件中沒有敘述的字段,這是因為java編譯器可能會在編譯時向類或者接口添加字段遇绞,添加進去的字段使用 Synthetic 屬性標識键袱。fields_descriptor 標識對應如所示:

    基本類型 含義
    B byte
    C char
    D double
    F float
    I int
    J long
    S short
    Z boolean
    V void
    L Object
    [ array(例如:[B ,表示 byte[] [Ljava/lang/String 表示 string[] ,多維數(shù)組 [[C [[[Ljava/lang/String)
  9. methods_count 和 methods
    在class文件中緊接著fields 后面的是對該類或者接口中所聲明的方法的描述摹闽。首先是名為 methods_count 的計數(shù)蹄咖,它是一個雙字節(jié)長度的對于該類或者接口中聲明的所有方法的總計數(shù)。這個總計數(shù)只包含在該類或者接口中顯式定義的方法(從超類或者父接口中集成來的方法不被計入)付鹿。
    方法表中的每個值都必須是method_info結構澜汤,該結構給出了這個類或接口中方法的完整描述铝量。如果在method_info結構的access_flags項中都沒有設置ACC_NATIVE和ACC_ABSTRACT標志,那么還會提供實現(xiàn)該方法的Java虛擬機指令银亲。

method_info結構表示由這個類或接口類型聲明的所有方法慢叨,包括實例方法、類方法务蝠、實例初始化方法和任何類或接口初始化方法拍谐。方法表不包括表示從超類或超接口繼承的方法的項。
如下所示:


image.png

圖中字節(jié)碼部分其實就是java 的匯編語言馏段,在 jvms 8 的第六轩拨、七章有說明,jvms 的下載地址為 https://docs.oracle.com/javase/specs/index.html院喜,值得注意的是一定要注意版本亡蓉。

  1. attributes_count 和 attributes
    class 文件中最后的部分是屬性(attribute),他給出了在改文件中類或者接口所定義的屬性的基本信息喷舀。屬性部分由 attributes_count 開始砍濒,attributes_count 是指出現(xiàn)在后續(xù) attributes 列表中的 attributes_info 表的數(shù)量總和。屬性表的每個值都必須是一個attribute_info結構硫麻,每個 attributes_info 的第一項是指向常量池中 CONSTANT_Utf8_info表的索引爸邢,該表給出了屬性的名稱。
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拿愧,一起剝皮案震驚了整個濱河市杠河,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌浇辜,老刑警劉巖券敌,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異柳洋,居然都是意外死亡待诅,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進店門膳灶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來咱士,“玉大人,你說我怎么就攤上這事轧钓。” “怎么了锐膜?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵毕箍,是天一觀的道長。 經(jīng)常有香客問我道盏,道長而柑,這世上最難降的妖魔是什么文捶? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮媒咳,結果婚禮上粹排,老公的妹妹穿的比我還像新娘。我一直安慰自己涩澡,他們只是感情好顽耳,可當我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著妙同,像睡著了一般射富。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上粥帚,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天胰耗,我揣著相機與錄音,去河邊找鬼芒涡。 笑死柴灯,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的费尽。 我是一名探鬼主播弛槐,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼依啰!你這毒婦竟也來了乎串?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤速警,失蹤者是張志新(化名)和其女友劉穎叹誉,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體闷旧,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡长豁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了忙灼。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片匠襟。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖该园,靈堂內(nèi)的尸體忽然破棺而出酸舍,到底是詐尸還是另有隱情,我是刑警寧澤里初,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布啃勉,位于F島的核電站,受9級特大地震影響双妨,放射性物質(zhì)發(fā)生泄漏淮阐。R本人自食惡果不足惜叮阅,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望泣特。 院中可真熱鬧浩姥,春花似錦、人聲如沸状您。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽竞阐。三九已至缴饭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間骆莹,已是汗流浹背颗搂。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留幕垦,地道東北人丢氢。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像先改,于是被迫代替她去往敵國和親疚察。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容