【发布时间】:2013-11-21 21:19:20
【问题描述】:
我有一个瓶颈方法,它试图将点(作为 x-y 对)添加到 HashSet。常见的情况是集合已经包含在这种情况下什么都不会发生的点。我应该使用一个单独的点来添加我用来检查集合是否已经包含它的点吗?似乎这将允许 JVM 在堆栈上分配检查点。因此,在一般情况下,这不需要堆分配。
例如。我正在考虑改变
HashSet<Point> set;
public void addPoint(int x, int y) {
if(set.add(new Point(x,y))) {
//Do some stuff
}
}
到
HashSet<Point> set;
public void addPoint(int x, int y){
if(!set.contains(new Point(x,y))) {
set.add(new Point(x,y));
//Do some stuff
}
}
是否有一个分析器可以告诉我对象是分配在堆上还是栈上?
编辑:为了澄清为什么我认为第二个可能更快,在第一种情况下,对象可能会或可能不会添加到集合中,因此它不是非转义且无法优化。在第二种情况下,分配的第一个对象显然是非转义的,因此它可以由 JVM 优化并放入堆栈。第二次分配只发生在它尚未被包含的极少数情况下。
【问题讨论】:
-
对象总是在堆上。参考将在堆栈上。
-
我不明白为什么第二个代码在性能或内存使用方面应该更好!如果尚未包含该点,则您将创建两次。通常,所有对象都在堆上创建(有不同种类的“堆”,这取决于 VM)。只有在逃逸分析的情况下,VM 才可能决定不“真正”创建第一个点。
-
我认为JVM可以识别非转义对象并将它们分配到堆栈上。请参阅这篇文章:stefankrause.net/wp/?p=64 我正在尝试通过使我的对象不转义来帮助 JVM 退出
-
是的,但你不应该依赖它。
-
为什么不呢?我的论点有什么问题?
标签: java optimization jvm stack