學(xué) JVM 是要學(xué)寫什么臭挽,掌握到什么程度捂襟?
作為使用者需要了解基本結(jié)構(gòu)。只是看靜態(tài)的結(jié)構(gòu)比較枯燥欢峰,且難以理解結(jié)構(gòu)的作用葬荷,為什么要這樣設(shè)計(jì),另外也不知道自己了解的深度夠不夠纽帖。
學(xué)習(xí)字節(jié)碼宠漩,可以讓你在 JVM 的工作過程中看結(jié)構(gòu)如何發(fā)揮作用&聯(lián)動(dòng),這樣就會(huì)生動(dòng)得多懊直,并且到字節(jié)碼這個(gè)程度理解結(jié)構(gòu)扒吁,深度也夠了。
字節(jié)碼表
Java bytecode 叫字節(jié)碼室囊,就是 8 位的瘦陈,現(xiàn)在也還沒用完,也就是說還沒超過 128 個(gè)波俄。在 JVM 里面這些就是最原子的操作符了晨逝。
一些有意思的設(shè)計(jì)
iload_0: load an int value from local variable 0
iload: load an int value from a local variable #index
iload_0 后面不需要再跟一個(gè)字節(jié)表示第幾個(gè) local variable,這樣設(shè)計(jì)是節(jié)省字節(jié)碼文件的空間的懦铺。有很多類似的設(shè)計(jì)捉貌。
工作機(jī)制
宏觀一點(diǎn)看,Java 程序是從一個(gè)入口方法進(jìn)入執(zhí)行一個(gè)接一個(gè)的方法冬念,直到退出趁窃。微觀一點(diǎn),方法的結(jié)構(gòu)就是一行一行的字節(jié)碼急前,JVM 就是讀取字節(jié)碼的指令醒陆,一步步操作。
根據(jù)我接觸到的字節(jié)碼裆针,我理解主要是三種類型
- push data into operand stack
數(shù)據(jù)來源可能是 local variables刨摩, constant pool 也可能字節(jié)碼自帶了數(shù)據(jù)寺晌,比如 iconst_0 - pop data from operand stack & do sth
比如
fcmpl: 按 float 型 pop 出兩個(gè)數(shù)據(jù),比較大小澡刹,根據(jù)比較結(jié)果 push 一個(gè) int 型到 stack 里
ifle: 按 int 型 pop 出一個(gè)數(shù)據(jù)呻征,和 0 比較,若小于等于則跳轉(zhuǎn)到 ifle 后面跟著的 branchoffset 處 - 對(duì) operand stack 沒有操作
goto