在java中设置null引用会有什么后果吗?

时间:2011-10-03 21:49:33

标签: java garbage-collection

如果我有一个指向某些java对象的引用,并执行类似的操作:

myObject=null;

JVM垃圾收集器是否可以正确释放旧对象的“丢失数据”? C中有类似的东西(带指针,会导致垃圾和可能的内存泄漏)。 我在java程序中使用null归属,现在想它是“安全的”。

6 个答案:

答案 0 :(得分:2)

假设没有对该对象的其他引用,这是为GC释放内存的好方法。 (实际上,除了弱引用之外,它基本上是唯一的方法:使对象无法从任何实时变量中访问。)请注意,一旦对象无法访问时,就没有时间表可以收集垃圾。

编辑:正如其他人所指出的那样,如果myObject无论如何都要超出范围,那么将myObject设置为null是不必要的。当变量本身不再可用作到达它引用的对象的路径时,GC系统是否包含引用或null无关紧要。

答案 1 :(得分:2)

如果myObject仅保留内存(比如大内部数组),那么将此引用设置为null就足够了。

另一方面,如果它包含您分配的其他资源(CloseableThreadExecutorService等),则必须注意正确关闭这些资源。

即使其中一些方法可能采用finalize方法,但系统调用时间太长(甚至从不),因此系统会产生理想的效果。

对于有人从C ++转换到Java的问题,这是一个非常常见的错误,我对此感到内疚。在我的第一个真正的Java项目中,我会定期用完文件句柄,因为在完成它们之后我没有调用close。毋庸置疑,如果使用512MB堆,GC就不会觉得有必要在为时已晚之前开始完成我的IO对象。

答案 2 :(得分:1)

是的,这就是JVM中垃圾收集器的用途。 JVM稍后可能会调用该对象的finalize方法,然后它可能会丢弃相关的存储。

答案 3 :(得分:1)

是,在以下情况下,引用指向的对象是符合条件的用于垃圾收集(如果没有其他实时引用该对象):

  1. 该方法返回 - 如果它最初是使用方法本地范围
  2. 创建的
  3. 立即 - 如果是实例或类变量

答案 4 :(得分:1)

您的假设是正确的,但您通常不需要专门这样做。

假设您的“myObject”用于另一个对象。在应用程序执行的生命周期中的某个时刻,此对象将停止被任何其他对象引用,因此将被GC标记为删除。它们的myObject也会被标记为删除。只要对给定对象的所有引用都消失,GC就会最终回收内存。

有(罕见)异常,例如事件处理,两个对象之间的依赖关系无法正确自动结束,并且最终可能会出现内存泄漏:当您在另一个类上订阅某个事件时,订阅者不能即使没有“直接”引用它也要收集。在这种特定情况下,手动清除链接可能会很有趣。

答案 5 :(得分:1)

是的,将Java对象引用(指针)设置为null有时是个好主意。这可能(如果没有对该对象的其他引用)可以比其他情况更快地“释放”该对象。当您拥有交织对象的大型“网络”时,这尤其有用。

在最坏的情况下,你需要花费一个额外的内存存储空间。