2015-06-09 117 views
5

在閱讀JVM規範時(正如一樣),當我遇到7 iconst_<i>操作碼時,我感到非常驚訝。畢竟,只有一個字節可以播放。爲什麼JVM具有iconst_2 - iconst_5操作碼?

我很少在我的代碼中編寫2,3,4或5的文字。我可以理解爲什麼-1,0和1可能會被特別對待,但對我來說,設計師想要將4個寶貴的操作碼打在剛好相當小的數字上似乎令人驚訝。

有誰知道這是否有充分的理由?我是否低估了這些好處?

+0

有255個可用的操作碼。在設計虛擬機指令集時,要使用它們附近的任何地方都很困難。很明顯,吉姆戈斯林認爲這是一個很好的DEA,並且在你用完之前它是免費的,比如贈送免費的劇院門票,爲什麼不呢? – EJP

回答

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_0iconst_4即使你在源代碼中沒有這樣的常量使用。

+0

好點,謝謝。 – user1675642

3

希望這能澄清你的問題爲什麼要浪費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說,這些數字會更經常使用比你想象