如果我有一个指向某些java对象的引用,并执行类似的操作:
myObject=null;
JVM垃圾收集器是否可以正确释放旧对象的“丢失数据”? C中有类似的东西(带指针,会导致垃圾和可能的内存泄漏)。 我在java程序中使用null归属,现在想它是“安全的”。
答案 0 :(得分:2)
假设没有对该对象的其他引用,这是为GC释放内存的好方法。 (实际上,除了弱引用之外,它基本上是唯一的方法:使对象无法从任何实时变量中访问。)请注意,一旦对象无法访问时,就没有时间表可以收集垃圾。
编辑:正如其他人所指出的那样,如果myObject无论如何都要超出范围,那么将myObject设置为null是不必要的。当变量本身不再可用作到达它引用的对象的路径时,GC系统是否包含引用或null无关紧要。
答案 1 :(得分:2)
如果myObject
仅保留内存(比如大内部数组),那么将此引用设置为null
就足够了。
另一方面,如果它包含您分配的其他资源(Closeable
,Thread
,ExecutorService
等),则必须注意正确关闭这些资源。
即使其中一些方法可能采用finalize
方法,但系统调用时间太长(甚至从不),因此系统会产生理想的效果。
对于有人从C ++转换到Java的问题,这是一个非常常见的错误,我对此感到内疚。在我的第一个真正的Java项目中,我会定期用完文件句柄,因为在完成它们之后我没有调用close
。毋庸置疑,如果使用512MB堆,GC就不会觉得有必要在为时已晚之前开始完成我的IO对象。
答案 2 :(得分:1)
是的,这就是JVM中垃圾收集器的用途。 JVM稍后可能会调用该对象的finalize
方法,然后它可能会丢弃相关的存储。
答案 3 :(得分:1)
是,在以下情况下,引用指向的对象是符合条件的用于垃圾收集(如果没有其他实时引用该对象):
答案 4 :(得分:1)
您的假设是正确的,但您通常不需要专门这样做。
假设您的“myObject”用于另一个对象。在应用程序执行的生命周期中的某个时刻,此对象将停止被任何其他对象引用,因此将被GC标记为删除。它们的myObject也会被标记为删除。只要对给定对象的所有引用都消失,GC就会最终回收内存。
有(罕见)异常,例如事件处理,两个对象之间的依赖关系无法正确自动结束,并且最终可能会出现内存泄漏:当您在另一个类上订阅某个事件时,订阅者不能即使没有“直接”引用它也要收集。在这种特定情况下,手动清除链接可能会很有趣。
答案 5 :(得分:1)
是的,将Java对象引用(指针)设置为null有时是个好主意。这可能(如果没有对该对象的其他引用)可以比其他情况更快地“释放”该对象。当您拥有交织对象的大型“网络”时,这尤其有用。
在最坏的情况下,你需要花费一个额外的内存存储空间。