6

嗨,我正在尝试找出为什么我的程序运行速度通常比我想要的慢,所以提前感谢您的帮助!


例如,我有一段代码,我想了解一下

1. while(conditionIsTrue){
2.      Object object = new Object();
3.  }

在第 2 行。我创建了一个新对象。这将在我的程序中发生数千次。null在 gc 将其销毁之前,我是否特别需要将旧对象取出?或者 gc 会在我的程序后面拾取其他对象使用的所有内存。

或者完全是另一种选择:正在分配一定数量的内存,每次我创建一个新对象时,它都会被分配给完全相同的内存。


Bruno 让我展示一段更真实的代码,以便我们弄清楚它运行缓慢的原因。但是,由于您的回答布鲁诺,我意识到我的代码是这样的

1. Object object = null;
2. while(conditionIsTrue){
3.      object = new Object();
4.  }

所以我意识到我对我的对象有很强的引用。谢谢布鲁诺!

4

2 回答 2

18

在这种情况下,您不需要object = null;允许 GC 清除new Object(),因为在实例化对象的迭代完成后(即第 3 行),没有对对象的引用。

规则是:只要不再有指向它的强引用,GC 就可以清除该对象。它可能不会立即清除对象,可能需要一些时间,但除非您设法获得对它的新强引用(是的,有办法!例如,请参阅) SoftReferenceWeakReference它最终会被清除,并且肯定会在它抛出之前被清除一个OutOfMemoryError

此外,JVM 在分配内存方面非常聪明。有一种叫做逃逸分析的东西:它允许 JVM 理解在new Object()循环之外的任何地方都没有使用,因此它甚至可以在堆栈上为对象分配内存,而不是在堆上!因此,该特定对象可能根本不需要 GC——当方法完成时,该对象会被自动清除。

我什至猜测 JVM 可能会检测到实例化该对象完全没有明显的影响,甚至可能只是选择不运行该行 #2(但这是一个猜测,如果我可能会考虑做一个优化正在编写一个编译器——如果有人确定是否会发生这种情况,请添加评论!)。

如果您的程序运行得比您希望的要慢,那么您必须展示一些更真实的代码。您可能会认为您的真实代码和您询问的代码片段之间存在细微差别,这对于 JVM 来说可能是一个巨大的差异!

于 2013-06-25T00:58:49.280 回答
1

知道您可以使用VisualVM之类的工具来查看您的程序如何使用内存、线程等也会很有帮助。

VisualVM 自版本 6 更新 7 起与 JDK 捆绑在一起,您可以在 JDK_HOME/bin 中找到它

于 2013-06-25T04:33:03.267 回答