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

标签 java memory jvm

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


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

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

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

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


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

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

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

最佳答案

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

规则是:当没有更多对象时,允许 GC 清除对象 strong references 指向它。它可能不会立即清除该对象,可能需要一些时间,但除非您设法获得对它的新强引用(是的,有办法!参见 SoftReferenceWeakReference 例如),它最终会被清除,当然在它抛出 OutOfMemoryError 之前.

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

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

如果你的程序运行速度比你希望它运行的慢,那么你必须展示一些更真实的代码。您可能认为真实代码与您询问的代码片段之间的细微差异对于 JVM 来说可能是巨大的差异!

关于java - 是否必须将引用设置为 null 才能使垃圾收集工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17287500/

相关文章:

java - 主窗口内的新窗口?

java - Jenkins Build 因 SVNException 而失败

c# - 统一: What's allocating memory in my function?

java - jvm堆设置模式

Hadoop DataNode 内存消耗和 GC 行为

java - NoClassDefFoundError org/eclipse/swt/SWTError

java - 创建 TypeVariable 实例

c++ - 多重继承后对类布局进行假设是否安全?

memory - 如果它们都需要两次内存访问,什么使 TLB 比页表更快?

java - JVM 因无限 GC 而挂起