在阅读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