为什么这个 java 代码不能使用逃逸分析?
why this java code can not use escape analysis?
我的代码在这里 =>
class PointHolder {
private Point point;
public PointHolder(Point point) {
this.point = point;
}
//getter
}
class Point {
private int x;
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
//getter setter
}
public class Escape {
public static void main(String[] args) {
for (int i = 0; i < 20000; i++) {
test4(i);
}
}
static int foo;
public static void test4(int x) {
PointHolder pointHolder = new PointHolder(new Point(x + 2, 42));
foo = pointHolder.getPoint().getX();
}
}
使用 jitwatch,我可以看到 pointHolder 没有被分配,但是 new Point(x+2, 42)
仍然被分配。
我想不通为什么
HotSpot C2 编译器中的逃逸分析相当简单。它从不尝试检测 all 未逃脱编译范围的可能对象。特别是,它目前不处理多级参考树。
在您的示例中,对新分配的 Point
的引用被分配给对象字段:PointHolder.point
。 JIT 将此分配视为 Point
对象的转义,因此不会消除分配。
一个特殊的例外是装箱-拆箱:HotSpot 专门处理装箱-拆箱方法。例如。当分配给 IntegerHolder
字段时,它仍然能够消除 Integer
对象的分配。
虽然这个问题并不是无法解决的问题 - 它只是错失了优化机会。 Graal JIT 在这个意义上更好——在给定的示例中,它 确实 消除了 Point
和 PointHolder
分配。
我的代码在这里 =>
class PointHolder {
private Point point;
public PointHolder(Point point) {
this.point = point;
}
//getter
}
class Point {
private int x;
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
//getter setter
}
public class Escape {
public static void main(String[] args) {
for (int i = 0; i < 20000; i++) {
test4(i);
}
}
static int foo;
public static void test4(int x) {
PointHolder pointHolder = new PointHolder(new Point(x + 2, 42));
foo = pointHolder.getPoint().getX();
}
}
使用 jitwatch,我可以看到 pointHolder 没有被分配,但是 new Point(x+2, 42)
仍然被分配。
我想不通为什么
HotSpot C2 编译器中的逃逸分析相当简单。它从不尝试检测 all 未逃脱编译范围的可能对象。特别是,它目前不处理多级参考树。
在您的示例中,对新分配的 Point
的引用被分配给对象字段:PointHolder.point
。 JIT 将此分配视为 Point
对象的转义,因此不会消除分配。
一个特殊的例外是装箱-拆箱:HotSpot 专门处理装箱-拆箱方法。例如。当分配给 IntegerHolder
字段时,它仍然能够消除 Integer
对象的分配。
虽然这个问题并不是无法解决的问题 - 它只是错失了优化机会。 Graal JIT 在这个意义上更好——在给定的示例中,它 确实 消除了 Point
和 PointHolder
分配。