深入理解java虛擬機(jī)讀書筆記,第八章:虛擬機(jī)字節(jié)碼執(zhí)行引擎

8.1概述

執(zhí)行引擎:輸入字節(jié)碼文件糊秆,處理過程是字節(jié)碼解析的等效過程武福,輸出的是執(zhí)行結(jié)果

8.2運(yùn)行時(shí)棧幀結(jié)構(gòu)

棧幀是虛擬機(jī)用于方法調(diào)用和方法執(zhí)行的數(shù)據(jù)結(jié)構(gòu),是虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū)的虛擬機(jī)棧的棧元素

棧幀存儲了方法的局部變量表扩然、操作數(shù)棧艘儒、動態(tài)連接、方法返回地址等信息

每一個方法從調(diào)用開始到執(zhí)行結(jié)束夫偶,就是棧幀在虛擬機(jī)棧中入棧出棧的過程

在編譯期間界睁,棧幀需要多大的局部變量表、多深的操作數(shù)棧都已經(jīng)完全確定兵拢,并且寫入方法的code 屬性中

一個棧幀需要分配多大內(nèi)存翻斟,不會受到程序運(yùn)行期變量數(shù)據(jù)影響

在活動線程中,棧頂?shù)臈攀怯行У乃盗澹Q為當(dāng)前棧幀访惜,相關(guān)聯(lián)的方法稱為當(dāng)前方法

8.2.1局部變量表

是一組變量值存儲空間,用于存放方法參數(shù)和方法內(nèi)部定義的局部變量

在Java程序編譯為class時(shí)腻扇,就在方法的code屬性的max_locals數(shù)據(jù)項(xiàng)中確定了該方法所需分配的局部變量表的最大容量

局部變量表的容量以變量槽slot為最小單位

一個slot可以存放一個32位以內(nèi)的數(shù)據(jù)债热,Java中32位以內(nèi)的數(shù)據(jù)類型有:boolean、byte幼苛、char窒篱、short、int舶沿、float、reference、returnAddress


通過Reference類型可以:

從此引用直接或者間接的獲取到對象在堆上存放的起始地址索引

此引用中直接或者間接的查找到對象所屬數(shù)據(jù)類型在方法區(qū)的存儲類型信息


對于64位(long畸冲,double)的數(shù)據(jù)類型,虛擬機(jī)采用高位對齊的方式為其分配兩個slot空間

虛擬機(jī)通過索引定位的方式使用局部變量表

方法執(zhí)行過程中召夹,虛擬機(jī)通過局部變量表完成變量值到參數(shù)列表的傳遞過程

對于實(shí)例方法岩喷,局部變量表中第0位索引的slot默認(rèn)傳遞方法所屬對象實(shí)例的引用

為了節(jié)省棧幀空間,slot空間可以重用,但是會有額外的副作用,例如影響垃圾收集

8.2.2操作數(shù)棧(操作棧)

是一個后入先出棧

在編譯時(shí)候?qū)懭隿ode屬性的max_stacks數(shù)據(jù)項(xiàng)中

操作數(shù)棧的每一個元素可以是任意的Java數(shù)據(jù)類型

32位數(shù)據(jù)類型占用的棧容量為1,64位數(shù)據(jù)類型占用的棧容量為2

操作數(shù)棧中元素的數(shù)據(jù)類型和字節(jié)碼指令的序列嚴(yán)格匹配

概念模型上渔扎,兩個棧幀完全相互獨(dú)立,但大多虛擬機(jī)做了優(yōu)化處理残吩,使兩個棧幀出現(xiàn)一部分重疊(方法調(diào)用可以共用一部分?jǐn)?shù)據(jù),無需進(jìn)行額外的參數(shù)復(fù)制傳遞)

8.2.3動態(tài)連接

每個棧幀都有一個指向運(yùn)行時(shí)常量池中該棧幀所屬方法的引用绰疤,持有這個引用是為了支持方法調(diào)用過程中的動態(tài)連接

8.2.4方法返回地址

正常完成出口:PC計(jì)數(shù)器的值可以作為返回地址榨了,棧幀中很可能保存這個計(jì)數(shù)值

異常完成出口:通過異常處理器表來確定返回地址呐粘,棧幀中一般不會保存這部分信息

方法退出等同于當(dāng)前棧幀出棧五芝,可能執(zhí)行的操作有:

恢復(fù)上層方法的局部變量表和操作數(shù)棧渐尿,把返回值(如果有的話)壓入調(diào)用者棧幀的操作數(shù)棧中殴穴,調(diào)整PC計(jì)數(shù)器的值以指向方法調(diào)用指令后面的一條指令

8.2.5附加信息


8.3方法調(diào)用

方法調(diào)用不等同于方法執(zhí)行,唯一任務(wù)就是確定被調(diào)用方法的版本

8.3.1解析

調(diào)用目標(biāo)在程序?qū)懞米鸩小⒕幾g器進(jìn)行編譯時(shí)就必須確定下來顷扩,這類方法的調(diào)用稱為解析

編譯期可知汹胃,運(yùn)行期不變

靜態(tài)方法

私有方法


相對應(yīng)的5條方法調(diào)用字節(jié)碼指令

invokestatic:調(diào)用靜態(tài)方法

invokespecial:調(diào)用實(shí)例構(gòu)造器init方法、私有方法、父類方法

invokevirtual:調(diào)用所有的虛方法

invokeinterface:調(diào)用接口方法挪拟,會在運(yùn)行時(shí)再確定一個實(shí)現(xiàn)此接口的對象

invokedynamic:現(xiàn)在運(yùn)行時(shí)動態(tài)解析出調(diào)用點(diǎn)限定符所引用的方法耘子,然后再執(zhí)行該方法


只要能被invokestatic和invokespecial指令調(diào)用的方法果漾,都可以再解析階段中確定唯一的調(diào)用版本球切,符合這個條件的由靜態(tài)方法谷誓、構(gòu)造方法、私有方法吨凑、父類方法四大類捍歪,這些方法稱為非虛方法(還包含final修飾的方法,無法被覆蓋鸵钝,沒有其他版本)糙臼;與之相反的稱為虛方法(final修飾除外)

8.3.2分派

靜態(tài)分派

靜態(tài)類型(外觀類型):變量本身的靜態(tài)類型不會被改變,最終的靜態(tài)類型是在編譯期可知的

實(shí)際類型:變化結(jié)果在運(yùn)行期才確定


使用哪個版本的重載恩商,完全取決于傳入?yún)?shù)的數(shù)量和數(shù)據(jù)類型变逃;虛擬機(jī)(準(zhǔn)確的說是編譯器)在重載時(shí)是通過參數(shù)的靜態(tài)類型而不是實(shí)際類型作為判定依據(jù);并且靜態(tài)類型是編譯期可知的怠堪,因此揽乱,在編譯階段,javac編譯器會根據(jù)參數(shù)的靜態(tài)類型決定使用哪個版本的重載


所有依賴靜態(tài)類型來定位方法執(zhí)行版本的分派稱為靜態(tài)分派

靜態(tài)分派的典型應(yīng)用就是方法重載


動態(tài)分派

重寫


invokevirtual的運(yùn)行時(shí)解析過程:

找到操作數(shù)棧頂?shù)牡谝粋€元素指向的對象的實(shí)際類型粟矿,記作C

如果類型C中找到與常量中的描述符和簡單名稱都相符的方法凰棉,則進(jìn)行訪問權(quán)限校驗(yàn),如果通過則返回這個方法的直接引用陌粹,查找過程結(jié)束撒犀,如果不存在,則返回java.lang.IllegalAccessError異常

否則掏秩,按照繼承關(guān)系從下往上依次對C的各個父類進(jìn)行第二步的查搜索和驗(yàn)證過程

如果始終沒有找到或舞,則拋出java.lang.AbstractMethodError異常

運(yùn)行期根據(jù)實(shí)際類型確定方法版本的分派稱為動態(tài)分派


單分派和多分派

方法的接受者方法的參數(shù)統(tǒng)稱為方法的宗量,根據(jù)分派基于多少種宗量蒙幻,可以將分派劃分為單分派和多分派

單分派是根據(jù)一個宗量對目標(biāo)方法進(jìn)行選擇

多分派是根據(jù)多于一個宗量對目標(biāo)方法進(jìn)行分派

靜態(tài)分派屬于多分派

動態(tài)分派屬于單分派


虛擬機(jī)動態(tài)分派的實(shí)現(xiàn)

方法表

8.3.3動態(tài)類型語言支持

動態(tài)類型語言

關(guān)鍵特征是類型檢查的主體過程是在運(yùn)行期而不是編譯期

變量無類型而變量值有類型

靜態(tài)類型語言在編譯期提供嚴(yán)謹(jǐn)?shù)念愋蜋z查

動態(tài)類型語言提供了更大的靈活性


JDK7與動態(tài)類型語言

invokedynamic指令以及java.lang.invoke包出現(xiàn)

java.lang.invoke包

提供了一種動態(tài)確定目標(biāo)方法的機(jī)制映凳,稱為MethodHandle


MethodHandle和反射(Reflection)區(qū)別:

本質(zhì)上將都是在模擬方法調(diào)用,但反射模擬Java代碼層次的調(diào)用杆煞,MethodHandle模擬字節(jié)碼層次的調(diào)用

反射中的java.lang.Method對象遠(yuǎn)比MethodHandle機(jī)制的java.lang.MethodHandle對象所彪悍的信息多魏宽,反射是重量級,MethodHandle是輕量級

MethodHandle優(yōu)化

invokedynamic指令

每一處含有invokedynamic指令的地方都稱為動態(tài)調(diào)用點(diǎn)

掌控方法分派規(guī)則


8.4基于棧的字節(jié)碼解釋執(zhí)行引擎

8.4.1解釋執(zhí)行

javac編譯器完成了程序代碼經(jīng)過詞法分析决乎、語法分析到抽象語法樹队询,在遍歷語法樹生成線性的字節(jié)碼指令流的過程

一部分在虛擬機(jī)之外進(jìn)行,而解釋器是在虛擬機(jī)內(nèi)部构诚,所以Java程序的編譯是半獨(dú)立的實(shí)現(xiàn)

8.4.2基于棧的指令集和基于寄存器的指令集

基于棧的指令集主要優(yōu)點(diǎn)是可移植性蚌斩、代碼更加緊湊、編譯實(shí)現(xiàn)更簡單范嘱;缺點(diǎn)是執(zhí)行速度相對慢點(diǎn)

8.4.3基于棧的解釋器執(zhí)行過程




參考文獻(xiàn):

[1] 深入理解Java虛擬機(jī) 第二版 --周志明

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末送膳,一起剝皮案震驚了整個濱河市员魏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌叠聋,老刑警劉巖撕阎,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異碌补,居然都是意外死亡虏束,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進(jìn)店門厦章,熙熙樓的掌柜王于貴愁眉苦臉地迎上來镇匀,“玉大人,你說我怎么就攤上這事袜啃『骨郑” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵群发,是天一觀的道長晰韵。 經(jīng)常有香客問我,道長也物,這世上最難降的妖魔是什么宫屠? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮滑蚯,結(jié)果婚禮上浪蹂,老公的妹妹穿的比我還像新娘。我一直安慰自己告材,他們只是感情好坤次,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著斥赋,像睡著了一般缰猴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上疤剑,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天滑绒,我揣著相機(jī)與錄音,去河邊找鬼隘膘。 笑死疑故,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的弯菊。 我是一名探鬼主播纵势,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了钦铁?” 一聲冷哼從身側(cè)響起软舌,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎牛曹,沒想到半個月后佛点,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡躏仇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年恋脚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片焰手。...
    茶點(diǎn)故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖怀喉,靈堂內(nèi)的尸體忽然破棺而出书妻,到底是詐尸還是另有隱情,我是刑警寧澤躬拢,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布躲履,位于F島的核電站,受9級特大地震影響聊闯,放射性物質(zhì)發(fā)生泄漏工猜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一菱蔬、第九天 我趴在偏房一處隱蔽的房頂上張望篷帅。 院中可真熱鬧,春花似錦拴泌、人聲如沸魏身。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽箭昵。三九已至,卻和暖如春回季,著一層夾襖步出監(jiān)牢的瞬間家制,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工泡一, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留颤殴,地道東北人。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓瘾杭,卻偏偏與公主長得像诅病,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評論 2 345

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