日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

Java虛擬機執(zhí)行引擎知識總結(jié)

瀏覽:22日期:2022-08-31 17:49:07

執(zhí)行引擎

也只有幾個概念, JVM方法調(diào)用和執(zhí)行的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)是 棧幀, 是內(nèi)存區(qū)域中 虛擬機棧中的棧元素, 每一個方法的執(zhí)行就對應(yīng)著一個棧幀在虛擬機棧中出棧入棧的過程.

棧幀:則是包含有局部變量表, 操作數(shù)棧, 動態(tài)連接, 方法返回地址, 附加信息.

1 局部變量表:

存儲單位是 slot, 一個slot占據(jù)32位, 對于64位的數(shù)據(jù)類型, 則是分配連續(xù)兩個slot空間. 而對于一個非靜態(tài)方法而言, 有一個隱藏參數(shù), 為 this, 而在局部變量表中的變量存儲順序則是

this -> 方法參數(shù) -> 方法體內(nèi)的變量(slot可以重用, 超出作用域即可復(fù)用.) 方法在編譯完成后, 其所需的空間已經(jīng)確定.

(這里也是需要注意的一個地方, 變量的作用域常常會覆蓋整個方法, 即使變量已經(jīng)不再使用, 但只要還在作用域內(nèi), 其slot空間就無法給其他變量使用, 因此, 最好是在需要使用到變量時, 定義在合理的作用域范圍內(nèi).)

2 操作數(shù)棧:

在操作數(shù)棧中需要注意,其數(shù)據(jù)類型必須與字節(jié)碼指令的序列嚴(yán)格匹配.

3 動態(tài)連接: 稍后詳解

4 方法返回地址:

方法有兩種退出方式, 正常退出, 異常退出, 當(dāng)正常退出后, 會恢復(fù)上層方法的局部變量表, 操作數(shù)棧, 并把方法返回結(jié)果壓入調(diào)用者的操作數(shù)棧.

方法調(diào)用

方法調(diào)用階段的唯一目的是, 確定調(diào)用方法的版本究竟是哪一個.

在Java虛擬機中提供了5條方法調(diào)用的相關(guān)指令:

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

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

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

invokeinterface: 調(diào)用所有的接口方法

invokedynamic: 先在運行時動態(tài)解析出調(diào)用點限定符所引用的方法, 然后再執(zhí)行該方法.

虛方法是非虛方法的補集, 什么是非虛方法呢? 能夠在編譯器就確定將要調(diào)用的究竟是哪個方法, 進而將該方法的符號引用 轉(zhuǎn)換為 相應(yīng)的直接引用的 方法就被稱作非虛方法.

我們知道在類加載時, 在相應(yīng)的類信息中, 存有對應(yīng)方法的相關(guān)信息, 常量池中存有相關(guān)直接引用. 在類加載的解析階段, 即會將這部分的符號引用轉(zhuǎn)換為直接引用.

那么什么方法才滿足這種條件呢?

能夠被invokespecial 和 invokestatic指令調(diào)用的方法, 都是可以在編譯器確定的方法, 即靜態(tài)方法, 私有方法, 父類方法(super.), 實例構(gòu)造器.

在final方法是個特殊點, 雖然final方法的執(zhí)行為 invokevirtual, 但它依然屬于非虛方法, 不難理解, final方法不能夠被重寫.

方法分派(dispatch)

1 靜態(tài)分派

對于代碼

Human man = new Man();

其中Human被稱為變量的靜態(tài)類型, 也叫外觀類型, 而 Man則是變量的實際類型. 而一個變量的靜態(tài)類型, 在聲明時即已經(jīng)確定, 僅僅在使用時才能夠臨時轉(zhuǎn)換靜態(tài)類型, 但變量本身的靜態(tài)類型并不會改變, 實際類型的變化只有在運行期才能確定.

//實際類型變化 Human man = new Man(); man = new Woman(); //靜態(tài)類型的變化 method((Man) man); method((Woman) man);

而當(dāng)我們在重載方法時, 向方法中傳入的參數(shù)類型, 即是靜態(tài)類型.因此 重載是一種 可以在編譯期就被確定執(zhí)行方法版本 的行為.

2 動態(tài)分派

動態(tài)分派 與 重寫息息相關(guān).

static class Human{ void sayHello() { System.out.println('human say hello'); } } static class Man extends Human{ @Override void sayHello() { System.out.println('man say hello'); } } void sayHello(Human man) { man.sayHello(); } public static void main(String[] args) { Human man = new Man(); Human human = new Human(); new Main().sayHello(man); new Main().sayHello(human); } //out: man say hello human say hello

結(jié)果不必多做解釋, 而現(xiàn)在的問題在于, 虛擬機如何知道, 究竟調(diào)用的是哪個方法?

0: new #3 // class Main$Man 3: dup 4: invokespecial #4 // Method Main$Man.'<init>':()V 7: astore_1 8: new #5 // class Main$Human 11: dup 12: invokespecial #6 // Method Main$Human.'<init>':()V 15: astore_2 16: new #7 // class Main 19: dup 20: invokespecial #8 // Method '<init>':()V 23: aload_1 24: invokevirtual #9 // Method sayHello:(LMain$Human;)V 27: new #7 // class Main 30: dup 31: invokespecial #8 // Method '<init>':()V 34: aload_2 35: invokevirtual #9 // Method sayHello:(LMain$Human;)V 38: return

其中主要關(guān)注幾個方法的執(zhí)行點, invokespecial不用多說, 之前提到過, 是執(zhí)行 構(gòu)造器方法時 的指令

而 invokevirtual 則正是執(zhí)行 main.sayHello(), 方法的指令, 指令的運行時解析過程大致如下:

而其中的關(guān)鍵點就在于, 取到的是 對象的實際類型.

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

2 如果在C中找到與描述符 和 簡單名稱都相符的方法, 進行訪問校驗, 如果可以則返回方法的直接引用, 否則拋出 IllegalAccessError異常

3 否則按照繼承關(guān)系 從下向上對C的各個父類進行第二步的搜索驗證過程.

4 如果始終找不到, 拋出異常.

動態(tài)類型語言

這也是要提到的關(guān)于 invokedynamic指令的主要目的。

動態(tài)類型語言的概念是: 意思就是類型的檢查是在運行時做的而非編譯期。

而Java本身則是靜態(tài)類型語言, 這一點又在哪里能夠體現(xiàn)呢?

obj.println('language');

如果處在java環(huán)境中,且obj的靜態(tài)語言類型是 java.io.PrintStream, 那么obj本身的實際類型也必須是PrintStream的子類才行, 哪怕本身存在 println方法也不可以, 但同樣的問題放在 javascript中就不同了, 只要實際類型中存在println方法, 執(zhí)行就不會有任何問題.

這點就是因為, java在編譯時已經(jīng)將其完整的符號引用生成出來, 如果注意到的話, 會發(fā)現(xiàn)無論是動態(tài)分派還是靜態(tài)分派, 在編譯的指令中都是已經(jīng)精確到相應(yīng)類的某一個方法中了, 如此, 自然只能夠在有限的范圍內(nèi)略做調(diào)整, 如果超出了當(dāng)前類的范圍, 就無法調(diào)用了.

jvm虛擬機并不僅僅是java語言的虛擬機, 那么如何為動態(tài)類型語言提供支持就是一個問題了, 并且在目前java8中的lamda表達(dá)式中也應(yīng)用的是 invokedynamic指令.

MethodHandle

而與之相關(guān)的jar包則是 java.lang.invoke, 相關(guān)的類則是 MethodHandle.

在這里我也并不想再談 MethodHandle的使用方法, 網(wǎng)上資料實在不少.

需要提到的是, 它的功能和java的反射略有相似, 通過方法名, class, 就可以調(diào)用相應(yīng)的方法. 但它比起反射要輕量級; 且Reflection是在模擬Java代碼的調(diào)用, MethodHandle是在模仿字節(jié)碼層面的調(diào)用.

這個方法不失為是在動態(tài)調(diào)用中除了反射之外的另一種選擇.

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

其實本文更像是在 前一篇博客中 java內(nèi)存區(qū)域中的虛擬機棧的一種補充說明.

而真實的執(zhí)行流程, 我想通過下文的代碼來看:

public int add() { int a = 100; int b = 200; int c = 300; return (a + b) * c;}-- javap -verbose Mainpublic int add();// 返回類型為 intdescriptor: ()Iflags: ACC_PUBLICCode://需要深度為2的操作數(shù)棧, 4個slot的局部變量空間, 有一個參數(shù)為 this stack=2, locals=4, args_size=1 //將100推入操作數(shù)棧頂, 棧:100 0: bipush 100 //將棧頂?shù)臄?shù)據(jù)出棧并存儲到局部變量表的第一個slot中(從0開始) //此時:棧: - 局部變量表: slot1 100 2: istore_1 //與上面類似,重復(fù)過程 3: sipush 200 6: istore_2 7: sipush 300 //此時:棧: - 局部變量表: slot1 100 slot2 200 slot3 300 10: istore_3 //將局部變量表 slot1的值復(fù)制到 棧頂 11: iload_1 //將局部變量表 slot2的值復(fù)制到 棧頂 此時:棧: 200 100 12: iload_2 //棧頂兩個元素出棧, 并相加, 結(jié)果重新入棧. 此時: 棧: 300 13: iadd //將局部變量表 slot3的值復(fù)制到 棧頂 此時:棧: 300 300 14: iload_3 //將棧頂元素相乘, 結(jié)果重新入棧 15: imul //將棧頂?shù)慕Y(jié)果返回給方法調(diào)用者. 方法執(zhí)行結(jié)束 16: ireturn LineNumberTable: line 85: 0 line 86: 3 line 87: 7 line 88: 11

基于棧的執(zhí)行引擎正是通過這樣出棧入棧的方式完成指令, 而基于寄存器的則不然, 是將操作數(shù)存入寄存器, 同時將輸入值也就是指令參數(shù) 與 某寄存器的存儲值相加. 區(qū)別就在于存儲位置, 以及參數(shù)問題, 基于棧的大部分指令都是無參數(shù)指令, 指令很明確的規(guī)定了 要用哪幾個棧元素, 棧元素的類型是什么.

我們平常所使用的電腦, 其 X86指令集, 正是基于寄存器的指令集.

優(yōu)缺點則是: 基于棧, 可移植性較強, 但速度比較慢, 慢的原因一是需要許多冗余操作, 代碼. 二是基于棧是基于內(nèi)存的操作方式, 而內(nèi)存的速度比起寄存器更是要慢上許多.

總結(jié)

本文大致介紹這樣幾點:

java多態(tài)在 jvm層次的實現(xiàn).

為什么說jvm執(zhí)行引擎是基于棧的執(zhí)行引擎, 以及究竟是怎樣一個流程.

以上就是Java虛擬機執(zhí)行引擎知識總結(jié)的詳細(xì)內(nèi)容,更多關(guān)于Java虛擬機執(zhí)行引擎的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Java
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
99久久激情| 成人在线视频免费| 亚洲天堂免费电影| 91一区二区| 久久久久久久久99精品大| 欧美不卡视频| 在线日韩视频| 日韩中文字幕亚洲一区二区va在线| 日韩中文字幕区一区有砖一区 | 国产精品一区二区精品| 国产精品香蕉| 热三久草你在线| 婷婷综合社区| 日韩精品中文字幕一区二区| 欧美a在线观看| 欧美日韩水蜜桃| 在线国产日韩| 久久久久伊人| 香蕉人人精品| 7m精品国产导航在线| 国产一区二区三区网| 亚洲精品1区| 深夜日韩欧美| 精品国产精品久久一区免费式| 成人午夜国产| 日韩av三区| 9999国产精品| 蜜臀av国产精品久久久久| 美女国产一区二区三区| 欧美日韩水蜜桃| 欧美亚洲色图校园春色| 亚洲国产欧美日本视频| 亚洲天堂日韩在线| 日本精品黄色| 亚洲另类视频| 四虎884aa成人精品最新| 五月国产精品| 日韩国产一区二区| 亚洲精品乱码日韩| 欧洲一区二区三区精品| 777久久精品| 亚洲激情婷婷| 麻豆成人综合网| 亚洲少妇自拍| 久久久久久色| 欧美肉体xxxx裸体137大胆| 欧美日韩午夜| 影音国产精品| 国产一区二区三区91| 蜜臀久久久久久久| 久久久久国产精品一区三寸| 国产欧美一区二区色老头| 国产一在线精品一区在线观看| 久久国产精品免费精品3p| 国产韩日影视精品| 大香伊人久久精品一区二区 | 日韩高清中文字幕一区二区| 亚洲美女久久精品| 国产精品多人| 亚洲综合婷婷| 亚洲女同一区| 日产精品一区| 国产精品啊啊啊| 日本一区福利在线| 亚洲欧美日韩在线观看a三区 | 欧美一区网站| 好看的亚洲午夜视频在线| 精品一区二区三区在线观看视频| 亚洲欧洲日韩| 亚洲欧美日韩精品一区二区| 久久精品卡一| 亚洲黄色免费看| 麻豆理论在线观看| 麻豆91在线播放| 国产精品九九| 国产精品日韩精品中文字幕| 亚洲精品大片| 亚洲精品字幕| 最新亚洲激情| 亚洲欧洲一区二区天堂久久| 99久久九九| 99视频精品全国免费| 国产在线看片免费视频在线观看| 精品国产日韩欧美精品国产欧美日韩一区二区三区 | 2023国产精品久久久精品双| av综合电影网站| 精品欠久久久中文字幕加勒比| 国产精品毛片aⅴ一区二区三区| 日本国产亚洲| 国产欧美日韩精品一区二区免费 | 久久国产精品色av免费看| 色8久久久久| 亚洲专区视频| 色综合视频一区二区三区日韩| 一区二区三区网站| 日韩在线视频一区二区三区| jiujiure精品视频播放| 午夜av一区| 亚洲一区观看| 中文在线日韩| 日韩高清三区| 欧美亚洲tv| 国产精品草草| 国产精品99久久免费观看| 久久av导航| 成人国产综合| 亚洲日本网址| 夜夜嗨一区二区| 四虎成人av| 欧美日韩中文一区二区| 中文精品在线| 视频在线观看国产精品| 亚洲美女91| 国产精品尤物| 日韩成人精品一区二区| 久久影院一区| 亚洲精品大片| 国产一区二区三区网| 999国产精品视频| 国产精品普通话对白| 日欧美一区二区| 美女在线视频一区| 国产99在线| 久色成人在线| 国产精品分类| 亚洲一级黄色| 亚洲毛片视频| 精品日韩一区| 日韩视频在线一区二区三区 | 久久九九国产| 国产精品老牛| 国产精品jk白丝蜜臀av小说| 日韩88av| 日韩精品一卡二卡三卡四卡无卡| 97成人超碰| 欧美精品高清| 日本v片在线高清不卡在线观看| 国产一区二区视频在线看| 久久av一区| 成人高清一区| 日韩在线视频一区二区三区| 国产精品久久久久蜜臀| 午夜一级久久| 国产精品a级| 国产亚洲福利| 久久一区视频| 亚洲色图综合| 秋霞国产精品| 91精品国产自产观看在线| 麻豆视频在线看| 日韩欧美中文字幕在线视频| 成人福利av| 国产调教一区二区三区| 蜜臀av免费一区二区三区| 国产精品一区二区三区av麻| 怡红院精品视频在线观看极品| 精品三区视频| 日韩国产在线观看| 欧美69视频| 国产成人精品一区二区免费看京 | 亚洲婷婷免费| 国产精品伦一区二区| 视频在线观看一区| 久久在线电影| 91偷拍一区二区三区精品| 日本午夜精品一区二区三区电影 | 日本一区二区高清不卡| 日韩中文字幕一区二区三区| 欧美成人基地| 国产精品66| 蜜臀久久久99精品久久久久久| 91精品国产自产在线观看永久∴| 蜜桃精品视频| 日本天堂一区| 亚洲九九精品| 亚洲精品电影| 99久精品视频在线观看视频| 精品国产精品久久一区免费式| 日韩午夜视频在线| 99视频+国产日韩欧美| 日韩精品永久网址| 久久香蕉网站| 日本视频在线一区| 蜜桃av一区二区三区电影| 韩国精品主播一区二区在线观看| 亚洲手机在线| 国产 日韩 欧美一区| 超级白嫩亚洲国产第一| 国产精品sm| 国产精品99久久久久久董美香| 午夜亚洲福利| 国产精品传媒麻豆hd| 欧美日韩在线观看首页| 免费日韩一区二区| 黄色成人精品网站| 99精品综合| 久久要要av| 国产成人精品三级高清久久91 | 涩涩涩久久久成人精品| 久久亚洲风情|