必须将引用设置为null才能使垃圾收集工作

sno*_*tia 6 java memory jvm

嗨,我试图发现为什么我的程序通常比我想要的慢,所以先谢谢你的帮助!


我有一段代码,我想深入了解一下

1. while(conditionIsTrue){
2.      Object object = new Object();
3.  }
Run Code Online (Sandbox Code Playgroud)

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

或者另一种选择是这种情况发生:正在分配一定量的内存,每次创建一个新的Object时,它都被分配给完全相同的内存.


布鲁诺让我展示一个更现实的代码片段,这样我们就可以找出它运行缓慢的原因.但是,由于你的答案Bruno我意识到我的代码是这样的

1. Object object = null;
2. while(conditionIsTrue){
3.      object = new Object();
4.  }
Run Code Online (Sandbox Code Playgroud)

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

Bru*_*eis 18

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

规则是:只要没有更多强引用指向它就允许GC清除对象.它可能不会立即清除对象,可能需要一些时间,但除非你设法获得新的强引用(是的,有方法!看到SoftReferenceWeakReference例如),它最终将被清除,当然它会抛出之前一个OutOfMemoryError.

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

我甚至会猜测JVM可能会检测到实例化该对象根本没有明显的效果,甚至可能只是选择不运行那条#2行(但这是一个猜测,如果我可以考虑进行优化正在编写一个编译器 - 如果有人确切知道这是否发生,请添加评论!).

如果你的程序的运行速度比你想运行它,那么你就必须表现出一些更现实的代码.您可能会认为您的实际代码与您询问的代码段之间的细微差别可能是JVM的巨大差异!