您好我试图发现为什么我的程序通常运行速度比我想要的慢,所以提前感谢您的帮助!
<小时/> 我有一段代码,我想深入了解一下
1. while(conditionIsTrue){
2. Object object = new Object();
3. }
第2行。我创建了一个新的Object。这将在我的程序中发生数千次。在gc销毁它之前,我是否特别要null
旧的Object?或者gc会在我的程序后面获取其他对象使用的所有内存。
或者另外一个选项就是这样:正在分配一定量的内存,每次创建一个新的Object时,它都被分配给那个完全相同的内存。
<小时/> 布鲁诺让我展示一个更现实的代码片段,这样我们就可以找出它运行缓慢的原因。但是,由于你的答案布鲁诺我意识到我的代码是这样的
1. Object object = null;
2. while(conditionIsTrue){
3. object = new Object();
4. }
所以我意识到我对我的对象有强烈的引用。谢谢布鲁诺!
答案 0 :(得分:18)
在这种情况下,您不需要object = null;
来允许GC清除new Object()
,因为在实例化对象完成的迭代之后,对象没有任何引用(就是第3行。
规则是:只要没有 strong references 指向它,就允许GC清除对象。它可能不会立即清除对象,可能需要一些时间,但除非你设法获得新的强引用(是的,有方法!例如,见SoftReference
和WeakReference
),它最终会被清除,当然它会抛出OutOfMemoryError
。
此外,JVM非常聪明地分配内存。有一些叫做 escape analysis 的东西:它允许JVM理解new Object()
没有在该循环之外的任何地方使用,所以它甚至可以为对象分配内存在堆栈上,而不是在堆上!因此,对于该特定对象可能根本不需要GC - 当方法完成时,对象将自动清除。
我甚至猜测JVM可能会检测到实例化该对象根本没有明显的效果,甚至可能只是选择不运行#2行(但这是一个猜测,我可能会想到一个优化)如果我正在编写编译器 - 如果有人确切知道这是否发生了,请添加注释!)。
如果您的程序运行速度低于,您希望它运行,那么您必须显示一些更实际的代码。您可能认为实际代码与您询问的代码段之间的微妙差异可能是JVM的巨大差异!
答案 1 :(得分:1)
了解您可以使用VisualVM之类的工具来查看程序如何使用内存,线程等,这也很有帮助。
从版本6更新7开始,VisualVM与JDK捆绑在一起,你可以在JDK_HOME / bin中找到它