当我从一些小的java函数中读取jvm字节码时,我发现当一个新的局部变量被计算在操作数堆栈上时,假设它将被存储在局部变量表中,但通常它会被加载到操作数立即堆栈(就字面字节而言)。我不太了解操作,这是不必要的操作吗?为什么java字节码“store”后面经常会出现“load”?
回答
Java编译器倾向于以一种非常简单直接的方式编译事物,并将优化留给JIT。
例如,如果你写x *= 3; x *= 4;
,你可能会得到字节码沿
iload_1
iconst_3
imul
istore_1
iload_1
iconst_4
imul
istore_1
编译器的线在理论上弄清楚,商店/对负载是多余的,将其删除。但有几个理由不这样做 - 1)这增加了很多复杂性,因为JIT无论如何优化了所有内容2)它使调试变得更加困难,因为您不再能够访问所有局部变量的值3)如果在该表达式的中间以某种方式抛出异常,则局部变量将具有不正确的值。
综观dspin
字节码
Method void dspin()
0 dconst_0 // Push double constant 0.0
1 dstore_1 // Store into local variables 1 and 2
2 goto 9 // First time through don't increment
5 dload_1 // Push local variables 1 and 2
6 dconst_1 // Push double constant 1.0
7 dadd // Add; there is no dinc instruction
8 dstore_1 // Store result in local variables 1 and 2
9 dload_1 // Push local variables 1 and 2
10 ldc2_w #4 // Push double constant 100.0
13 dcmpg // There is no if_dcmplt instruction
14 iflt 5 // Compare and loop if less than (i < 100.0)
17 return // Return void when done
唯一load
下面store
是在偏移量9可以看到,偏置9可以通过两个不同的路径到达:(1)从偏移2与goto 9
;和(2)从偏移量开始顺序8
dload_1
将局部变量1和2的值推送到操作数堆栈(两个变量因为double
):如果(1)第一次尝试进入循环时, (2)在稍后的时间点尝试进入循环时。
有趣的是,在本例中,如果您删除所有store
和load
,程序的行为不会改变。但是,Java编译器通常不会很聪明。它或多或少地直接编译Java代码。在这种情况下,局部变量i
直接对应于局部变量1和2.
请参阅Optimization by Java Compiler了解更多信息。
如果我删除所有'store'和'load',那么上面的代码是否仍然可以工作? –
@Q_SJ,请参阅编辑答案。 – dejvuth
如果我正确理解你,你的意思是在某些情况下,javac确实会生成一对“存储”和“加载”。我对吗? –
- 1. Java ASM如何读取LOAD或STORE字节码的值
- 2. java - 为什么这个字节不会引起异常?
- 3. 为什么使用LOAD DATA INFILE时会出现错误?
- 4. 在java中读取datainputstream时,为什么会出现EOF异常?
- 5. 为什么会.load在IE8
- 6. 为什么动态更改Webservice Url后会出现异常?
- 7. 这个字符为什么会出现?
- 8. 为什么Class.forName出现在这个类的字节码中?
- 9. 运行此代码后,为什么会出现Ajax错误?
- 10. 为什么会话ID经常变化?
- 11. 为什么会出现在
- 12. 为什么会出现NullPointerException?
- 13. 为什么会出现NullPointerException?
- 14. 为什么会出现ConcurrentModificationException?
- 15. 为什么会出现idlelib.sys
- 16. 为什么不会出现后退按钮出现此代码(UINavigationController问题)
- 17. 编码JSON字符串时,为什么会出现前导0?
- 18. 为什么发生字节溢出,它们实现了什么?
- 19. 为什么一些货币符号出现在数字后面?
- 20. jquery load()后会发生什么?
- 21. 为什么经常出现<! - 风格标签内部?
- 22. 为什么jquery在.load()后面看到页面的变化?
- 23. 为什么异常(抛出:SecurityException:Permisssion拒绝)出现在下面的代码
- 24. 为什么在解析为整数时会出现异常?
- 25. 为什么会出现这种输出?
- 26. 什么是Java字节码中的#号?
- 27. 什么是Java字节码注入?
- 28. 为什么Java在Java中没有指针时会出现“NullPointerException”?
- 29. 为什么在调用ExtJS Grid Store Load时会执行太多的请求?
- 30. Facebook的页面怎么了为什么会出现碎片
请举例。很难说,否则你在说什么。不可能,真的。 – EJP
请详细说明您的问题。 –
你不可能在评论中令人满意地回答这个问题。将它编辑到你的问题中,它应该放在首位。 – EJP