2015-06-09 113 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说,这些数字会更经常使用比你想象