在閱讀JVM規範時(正如一樣),當我遇到7 iconst_<i>
操作碼時,我感到非常驚訝。畢竟,只有一個字節可以播放。爲什麼JVM具有iconst_2 - iconst_5操作碼?
我很少在我的代碼中編寫2,3,4或5的文字。我可以理解爲什麼-1,0和1可能會被特別對待,但對我來說,設計師想要將4個寶貴的操作碼打在剛好相當小的數字上似乎令人驚訝。
有誰知道這是否有充分的理由?我是否低估了這些好處?
在閱讀JVM規範時(正如一樣),當我遇到7 iconst_<i>
操作碼時,我感到非常驚訝。畢竟,只有一個字節可以播放。爲什麼JVM具有iconst_2 - iconst_5操作碼?
我很少在我的代碼中編寫2,3,4或5的文字。我可以理解爲什麼-1,0和1可能會被特別對待,但對我來說,設計師想要將4個寶貴的操作碼打在剛好相當小的數字上似乎令人驚訝。
有誰知道這是否有充分的理由?我是否低估了這些好處?
我認爲,你的假設是正確的:只是爲了使字節碼更小,並且Java解釋器速度稍快一點(這些時候沒有JIT編譯器)。請注意,這些字節碼可能比您預期的要頻繁得多。例如,請考慮下面的代碼:
int[] a = {10, 20, 30, 40};
有效它編譯成類似:
int[] a = new int[4];
a[0] = 10;
a[1] = 20;
a[2] = 30;
a[3] = 40;
所以這裏iconst_0
到iconst_4
即使你在源代碼中沒有這樣的常量使用。
好點,謝謝。 – user1675642
希望這能澄清你的問題爲什麼要浪費4個操作碼..
看到這個代碼的一部分字節碼
0: bipush 20
2: istore_1
3: iconst_5
4: istore_2
5: bipush 6
7: istore_3
的
public static void main(String[] args) {
int b = 20;
int c = 5;
int d= 6;
}
的字節碼正如你可以看到對於大於5的數字,它開始使用bipush
,它通常比等效的iconst_<n>
效率低,並且在類文件中佔用更多字節。
bipush
byte1
膨脹byte1
爲int,然後將其推到 堆,因爲Java堆棧上的每個時隙是32個位寬(JVM是基於堆棧的虛擬機)
而且看如果bipush
佔用更多的字節 ..
見以下兩個代碼的類文件的大小。(該尺寸是我的64位計算機上..它可能會有所不同您的計算機上,但差別會SAM E)
public class Test2 {
public static void main(String[] args) {
int b = 5;
}
}
現在,如果我更換尺寸406字節
b =6
; 相同類文件的大小變爲407 bytes
,它保持恆定,直到b=127
也使用bipush
。在尺寸這種差異是由於bipush有2個字節,一個字節的操作碼,第二個字節即時constat值的事實
bipush格式:
bipush
byte
,你可以從字節碼線5: bipush 6
見而iconst_<n>
只使用1個字節。
所以例如字節代碼被一些常用推數定義,以 增加字節碼執行的效率和減少的 字節碼流的大小。
和Tagir說,這些數字會更經常使用比你想象
有255個可用的操作碼。在設計虛擬機指令集時,要使用它們附近的任何地方都很困難。很明顯,吉姆戈斯林認爲這是一個很好的DEA,並且在你用完之前它是免費的,比如贈送免費的劇院門票,爲什麼不呢? – EJP