我尝试使用此命令在Test类下面进行反汇编:
java -XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*Test.main Test > log.txt
测试类:
public class Test {
static {
System.out.println("loading Test");
}
public static void main(String[] args) {
Aze a = new Aze(1,2,3);
Baz b = new Baz();
}
}
class Aze {
private String toto ;
private int titi ;
private int tata ;
public Aze(int a, int b, int c) {
this.toto = "azertyu";
this.titi = b;
this.tata = c;
}
}
class Baz extends Aze {
public Baz() {
super(1,2,3);
}
}
但结果并不包含任何汇编代码:
CompilerOracle: print *Test.main Java HotSpot(TM) Client VM warning: printing of assembly code is enabled; turning on DebugNonSafepoints to gain additional output loading Test
如果我通过添加somme虚拟代码修改我的main方法:
long x = 0;
for (int i = 0; i < 100000; i++) {
x += i*i;
}
System.out.println("x=" + x);
它突然起作用,我得到的输出不仅与添加的代码有关。
例如,我发现像这样的装配线:
0x026f1843: mov $0x24655510,%edx ; {oop("azertyu")}
现在,如果我使用:for (int i = 0; i < 10000; i++)
修改for循环,我只有结果行x=333283335000
,但根本没有汇编代码。
所以我不明白为什么我无法获得所有程序的汇编代码?
答案 0 :(得分:2)
只显示“just-in-time-compiled”代码,因为这是唯一的汇编程序,其余的是解释字节代码。
对于最初的程序来说,没有什么工作要做,所以没有编译,即一切只是解释。您在程序中执行的循环和内容越多,编译器就越多。
关于什么将被编译以及什么时候,几乎没有(没有?)保证。
你的“azertyu”组装的原因可能是因为它是“不变的”,优化器在运行for
循环时发现了它。