这是我试图从Java Performance: The Definitive Guide, Page 97关于Escape Analysis主题复制的示例。这可能是应该发生的事情:
getSum()
必须变得足够热,并且必须使用适当的 JVM 参数将其内联到调用者main()
中。- 由于
list
和sum
变量都不会从main()
方法中逃脱,它们可以被标记为NoEscape
因此 JVM 可以为它们使用堆栈分配而不是堆分配。
但是我通过jitwatch运行它,结果显示它getSum()
编译成本地程序集并且没有内联到main()
. 更不用说因此堆栈分配也没有发生。
我在这里做错了什么?(我已经把整个代码和热点日志放在这里了。)
这是代码:
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.stream.IntStream;
public class EscapeAnalysisTest {
private static class Sum {
private BigInteger sum;
private int n;
Sum(int n) {
this.n = n;
}
synchronized final BigInteger getSum() {
if (sum == null) {
sum = BigInteger.ZERO;
for (int i = 0; i < n; i++) {
sum = sum.add(BigInteger.valueOf(i));
}
}
return sum;
}
}
public static void main(String[] args) {
ArrayList<BigInteger> list = new ArrayList<>();
for (int i = 1; i < 1000; i++) {
Sum sum = new Sum(i);
list.add(sum.getSum());
}
System.out.println(list.get(list.size() - 1));
}
}
我使用的JVM参数:
-server
-verbose:gc
-XX:+UnlockDiagnosticVMOptions
-XX:+TraceClassLoading
-XX:MaxInlineSize=60
-XX:+PrintAssembly
-XX:+LogCompilation