From:深入理解Java虛擬機(jī)
- 目錄
BiBi - JVM -0- 開篇
BiBi - JVM -1- Java內(nèi)存區(qū)域
BiBi - JVM -2- 對(duì)象
BiBi - JVM -3- 垃圾收集算法
BiBi - JVM -4- HotSpot JVM
BiBi - JVM -5- 垃圾回收器
BiBi - JVM -6- 回收策略
BiBi - JVM -7- Java類文件結(jié)構(gòu)
BiBi - JVM -8- 類加載機(jī)制
BiBi - JVM -9- 類加載器
BiBi - JVM -10- 虛擬機(jī)字節(jié)碼
BiBi - JVM -11- 編譯期優(yōu)化
BiBi - JVM -12- 運(yùn)行期優(yōu)化
BiBi - JVM -13- 并發(fā)
Java虛擬機(jī)具有平臺(tái)無關(guān)【W(wǎng)indow蜕着、Mac】和語言無關(guān)【Groovy、JPython汽馋、JRuby】的特性侮东。Java虛擬機(jī)只與【Class文件】這種特定的二進(jìn)制文件格式關(guān)聯(lián),不與任何語言綁定豹芯。所有會(huì)有javac編譯器悄雅、groovyc編譯器、jrubyc編譯器等來產(chǎn)class文件铁蹈。
Class文件
Class文件是一組以8位字節(jié)【64位】為基礎(chǔ)單位的二進(jìn)制流宽闲,之間沒有添加任何分隔符。當(dāng)遇到需要占用8位字節(jié)以上空間的數(shù)據(jù)項(xiàng)時(shí)握牧,會(huì)按照高位在前的方式分割成若干個(gè)8位字節(jié)進(jìn)行存儲(chǔ)容诬。
Javap是一個(gè)專門用于分析Class文件字節(jié)碼的工具。
Class文件格式中只有兩種數(shù)據(jù)類型:無符號(hào)數(shù)和表沿腰。
無符號(hào):基本的數(shù)據(jù)類型览徒,u1 u2【2個(gè)字節(jié)】 u4 u8,無符號(hào)數(shù)可以用來描述:數(shù)字颂龙、索引引用习蓬、數(shù)量值、字符串值等措嵌。
表:是由多個(gè)無符號(hào)數(shù)構(gòu)成的復(fù)合數(shù)據(jù)類型躲叼,習(xí)慣以【_info】結(jié)尾。
當(dāng)需要描述一類型但數(shù)量不定的多個(gè)數(shù)據(jù)時(shí)企巢,會(huì)使用一個(gè)前置的容量計(jì)數(shù)器 + 若干這連續(xù)的數(shù)據(jù)項(xiàng)枫慷,稱這為某一類型的集合。
Class文件結(jié)構(gòu)
Class文件的頭4個(gè)字節(jié)【0xCAFFBABE,咖啡寶貝】稱為【魔數(shù)】或听,標(biāo)識(shí)該文件是否為一個(gè)能被虛擬機(jī)接受的Class文件探孝,即進(jìn)行身份驗(yàn)證。
緊接著魔數(shù)的4個(gè)字節(jié)標(biāo)識(shí)Class文件的版本號(hào):其中第5神帅、6字節(jié)是次版本號(hào)再姑;第7萌抵、8字節(jié)是主版本號(hào)【Java的版本號(hào)從45開始】找御。該信息主要是為了版本兼容,高版本的JDK能兼容低版本的Class文件绍填,但低版本的JDK不能運(yùn)行高版本的Class文件霎桅。
緊接著版本號(hào)之后的是常量池入口,由于數(shù)量不固定讨永,所以入口有一個(gè)u2類型的數(shù)據(jù)滔驶,代表常量池容量的計(jì)數(shù)值。如:0x0016卿闹,代表常量池中有21項(xiàng)常量揭糕。【只有常量池的索引從1開始】其中锻霎,第0項(xiàng)表示:不引用任何一個(gè)常量池的項(xiàng)目著角。常量池中主要存放兩大常量:字面常量和符號(hào)引用。
字面常量:文本字符串旋恼、final常量值吏口。
符號(hào)引用:類和接口的全限定名、字段的名稱和描述符冰更、方法的名稱和描述符产徊。
虛擬機(jī)加載Class文件是動(dòng)態(tài)連接的,即在Class文件中不會(huì)保存各個(gè)方法和字段的最終內(nèi)存布局信息蜀细,因此這些字段舟铜、方法的符號(hào)引用不經(jīng)過運(yùn)行期轉(zhuǎn)換,無法得到真正的內(nèi)存入口地址奠衔,也就無法直接被虛擬機(jī)使用谆刨。當(dāng)虛擬機(jī)運(yùn)行時(shí),需要從常量池獲得對(duì)應(yīng)的符號(hào)引用涣觉,再在類創(chuàng)建時(shí)或運(yùn)行時(shí)解析痴荐、翻譯到具體內(nèi)存地址之中。
- 緊接著的是:
訪問標(biāo)志官册;
類索引生兆、父類索引、接口索引集合;
字段表集合鸦难;
方法表集合根吁;
屬性表集合『媳危【跟我們平時(shí)理解的「屬性」不是一回事】
字節(jié)碼指令
Java虛擬機(jī)規(guī)范描繪了Java虛擬機(jī)應(yīng)有的共同程序存儲(chǔ)格式:Class文件格式和字節(jié)碼指令集击敌。Java虛擬機(jī)的指令由一個(gè)字節(jié)【8位】長度的,代表著某種特定操作含義的數(shù)字【操作碼】以及跟隨其后的零至多個(gè)代表此操作所需參數(shù)【操作數(shù)】而構(gòu)成拴事。
Java虛擬機(jī)采用面向操作數(shù)棧而不是寄存器的架構(gòu)沃斤,所以大多數(shù)的指令都不包含操作數(shù),只有一個(gè)操作碼刃宵。在Java虛擬機(jī)的指令集中衡瓶,大多數(shù)的指令都包含了其操作所對(duì)應(yīng)的數(shù)據(jù)類型信息。如:iload牲证、fload哮针。
- 加載和存儲(chǔ)指令
- 運(yùn)算指令
- 類型轉(zhuǎn)換指令
- 對(duì)象創(chuàng)建與訪問指令
- 操作數(shù)棧管理指令
- 控制轉(zhuǎn)移指令
- 方法調(diào)用和返回指令
- 異常處理指令
- 同步指令