日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

JAVA字节码指令iload_n为什么只有0到3?

發(fā)布時(shí)間:2024/4/11 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JAVA字节码指令iload_n为什么只有0到3? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

點(diǎn)擊上方“朱小廝的博客”,選擇“設(shè)為星標(biāo)”

后臺(tái)回復(fù)"書",獲取

后臺(tái)回復(fù)“k8s”,可領(lǐng)取k8s資料

來源:r6d.cn/ZxLw

這是Java字節(jié)碼上針對(duì)字節(jié)碼大小的一個(gè)早期優(yōu)化。從現(xiàn)在的角度看它可能算是一種過早優(yōu)化(premature optimization)了。

Java字節(jié)碼指令集里,大部分跟局部變量打交道的指令(例如<type>load、<type>store)都有完整版:

<type>load?n

例如iload 5,以及針對(duì)頭4個(gè)局部變量/參數(shù)的縮寫版:

<type>load_<n>

例如iload_0,這樣兩個(gè)版本。其中,縮寫版,正如標(biāo)題所說,只有0~3的范圍。

它們的區(qū)別是,前者有顯式的“操作數(shù)”(operand),而后者是把操作數(shù)融合到了操作碼(opcode)里面。看iload與iload_<n>的例子就很清楚:

iload的指令格式是:Chapter 6. The Java Virtual Machine Instruction Set[1]

iload?index

其中"iload"是opcode,其值為21(0x15),而后面跟著一個(gè)unsigned byte作為index來指定局部變量的下標(biāo)。另外還有wide版,如果在iload前面帶有wide前綴的話,則格式為:

wide?iload?index1?index2

其中wide、iload、index1、index2各自為一個(gè)字節(jié),而 (index1 << 8) | index2 構(gòu)成指令局部變量下標(biāo)的操作數(shù)。

iload_的指令格式則是:Chapter 6. The Java Virtual Machine Instruction Set[2]

iload_<n>

其中iload_<n>自身就是opcode,它可能的取值為:iload_0 = 26 (0x1a)iload_1 = 27 (0x1b)iload_2 = 28 (0x1c)iload_3 = 29 (0x1d)這樣的話,針對(duì)頭4個(gè)局部變量,iload_<n>就可以只用一個(gè)字節(jié)的opcode來表達(dá)整條指令,比使用完整版的iload要少一個(gè)字節(jié)。使用縮寫版指令不但可以讓字節(jié)碼的大小減少,還可以讓解釋器(注意!只是解釋器)的性能提升。因?yàn)榻忉屍魍ǔ6紩?huì)有這樣的結(jié)構(gòu):

while?(true)?{opcode?=?*program_counter++;????//?fetch?opcode://???1?memory?read,?1?memory?writeswitch?(opcode)?{???????????????//?dispatch?opcodecase?some_instruction:operands?=?decode_operands();?//?decode?operands://???1~n?memory?readsperform_operation(operands);??//?actual?operationprogram_counter?+=?size_of_some_instruction;?//?1?memory?read,?1?memory?writebreak;} }

(解釋器有各種優(yōu)化方式,上面的形式是最簡(jiǎn)單的switch-threading,但 fetch-dispatch/decode-execute 的組成部分總是存在的)當(dāng)使用縮寫版指令時(shí),decode_operands()就不需要做任何額外的內(nèi)存讀,因?yàn)閛perand已經(jīng)隱藏在opcode里了,于是就會(huì)比完整版指令要快一些。

至于為啥選擇0~3的范圍來做縮短版,我不知道當(dāng)初JVM原始設(shè)計(jì)的過程中具體發(fā)生了怎樣的討論和設(shè)計(jì)取舍,但一種可以想像的可能性是:最初的JVM的解釋器已經(jīng)寫好了,看看1個(gè)字節(jié)的opcode能表達(dá)的256個(gè)opcode中已經(jīng)用了多少個(gè),然后再想想剩下的空余的那些可以用來做怎樣的局部?jī)?yōu)化。

大概是正好發(fā)現(xiàn),如果用0~3的話可以基本上把opcode范圍用滿(JVM規(guī)范里使用了的opcode范圍比Sun最初的JVM內(nèi)部所使用的opcode范圍要小一些,因?yàn)镾un JVM使用了一些quick_系字節(jié)碼并沒有作為規(guī)范的一部分,而是在第一版JVM規(guī)范里作為額外的講解說剩余的編碼空間可以用來做quick_系指令的優(yōu)化),如果用例如說0~4的話就把1字節(jié)opcode編碼空間用超了,而0~2的話則用不滿。

就這樣而已。

于是早期的坊間傳說的Java程序性能優(yōu)化指引中,有一條是說:Java方法應(yīng)該盡量只使用不超過4個(gè)參數(shù)+局部變量,最頻繁使用的局部變量應(yīng)該放在前面,來想辦法使用上Java字節(jié)碼的這個(gè)縮寫版指令優(yōu)化。

然而后來JIT編譯器成為主流后,這種優(yōu)化指引就完全沒有用了。JIT編譯器根本不在乎輸入的字節(jié)碼是完整版還是縮寫版,都一樣對(duì)待。

參考資料

[1]

Chapter 6. The Java Virtual Machine Instruction Set: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iload

[2]

Chapter 6. The Java Virtual Machine Instruction Set: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iload_n

想知道更多?描下面的二維碼關(guān)注我

后臺(tái)回復(fù)"技術(shù)",加入技術(shù)群

后臺(tái)回復(fù)“k8s”,可領(lǐng)取k8s資料

【精彩推薦】

  • 原創(chuàng)|OpenAPI標(biāo)準(zhǔn)規(guī)范

  • 中臺(tái)不是萬能藥,關(guān)于中臺(tái)的思考和嘗試

  • ClickHouse到底是什么?為什么如此牛逼!

  • 原來ElasticSearch還可以這么理解

  • 面試官:InnoDB中一棵B+樹可以存放多少行數(shù)據(jù)?

  • 微服務(wù)下如何解耦?對(duì)于已經(jīng)緊耦合下如何重構(gòu)?

  • 如何構(gòu)建一套高性能、高可用、低成本的視頻處理系統(tǒng)?

  • 架構(gòu)之道:分離業(yè)務(wù)邏輯和技術(shù)細(xì)節(jié)

  • 星巴克不使用兩階段提交

點(diǎn)個(gè)贊+在看,少個(gè) bug?????

總結(jié)

以上是生活随笔為你收集整理的JAVA字节码指令iload_n为什么只有0到3?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。