在java中设置对null的引用有什么后果吗?
如果我有一个指向某个 java 对象的引用,并执行以下操作:
myObject=null;
旧对象的“丢失数据”是否会被 JVM 垃圾收集器正确释放? C 中类似的东西(使用指针,会导致垃圾和可能的内存泄漏)。 我在 java 程序中使用 null 归因,现在想知道它是否“安全”。
If I have a reference pointing to some some java object, and do something like:
myObject=null;
Will the "lost data" of the old object be correctly freed by the JVM Garbage Collector? Something similar in C (with a pointer, would result in trash and a possible memory leak).
I am using null attribution in a java program and would like to now if it is "safe".
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如果
myObject
仅保存内存(例如大型内部数组),则将此引用设置为null
就足够了。另一方面,如果它拥有您分配的其他类型的资源(
Closeable
、Thread
、ExecutorService
等),您必须注意正确关闭这些资源。即使其中一些可能有
finalize
方法,但它们可能被调用得太晚(甚至永远不会),以致您的系统无法达到理想的效果。对于从 C++ 转向 Java 的人来说,这是一个非常常见的错误,我对这里的指控感到内疚。在我的第一个真正的 Java 项目中,我会定期用完文件句柄,因为在处理完它们后我没有调用
close
。不用说,对于 512MB 的堆,GC 永远不会觉得有必要在为时已晚之前开始完成我的 IO 对象。If
myObject
only holds memory ( say large internal array ), then setting this reference tonull
is enough.If, on the other hand, it holds some other kind of resource that you've allocated (
Closeable
,Thread
,ExecutorService
, etc ), you must take care to properly shut down these resources.Even though some of them may have
finalize
method they may be called too late ( or even never ) for your system to have a desirable effect.It is a very common mistake for somebody switching from C++ to Java, and I am guilty as charged here. In my first real Java project I would periodically run out of file handle, because I was not calling
close
after being done with them. Needless to say with a 512MB heap, GC would never feel the need to start finalizing my IO objects before it was too late.假设没有其他对该对象的引用,这是为 GC 释放内存的好方法。 (实际上,除了弱引用等之外,它基本上是唯一的方法:使对象无法从任何活动变量访问。)请注意,一旦对象变得无法访问,就没有时间表来确定何时对其进行垃圾收集。
编辑:正如其他人指出的那样,如果 myObject 超出范围,则无需将 myObject 设置为 null 。当变量本身不再可用作到达其引用的对象的路径时,对于 GC 系统来说,它是否包含引用或 null 并不重要。
Assuming that there are no other references to the object, this is a good way to free memory up for the GC. (Actually, aside from weak references and the like, it's basically the only way: make the object unreachable from any live variables.) Note that there is no schedule for when an object might get garbage collected once it becomes unreachable.
EDIT: As others have pointed out, setting myObject to null is unnecessary if myObject is going out of scope anyway. When the variable itself is no longer available as a path to reach the object it references, then it doesn't matter to the GC system whether or not it contains a reference or null.
您的假设是正确的,但您通常不需要专门这样做。
假设您的“myObject”已在另一个对象中使用。在应用程序执行生命周期的某个时刻,该对象将停止被任何其他对象引用,因此将被 GC 标记为删除。它们 myObject 也将被标记为删除。一旦对给定对象的所有引用消失,GC 最终将回收内存。
有(罕见的)异常,例如事件处理,两个对象之间的依赖关系无法正确自动结束,并且可能会导致内存泄漏:当您订阅另一个类上的事件时,即使订阅者也无法被收集当没有“直接”引用它时。在这种特定情况下,手动清除链接可能会很有趣。
Your assumption is correct, but you don't usually need to specifically do that.
Let's say your "myObject" is used in another object. At some point in the lifetime of your application's execution, this object will stopped being referenced by any other object, and thus will be marked for deletion by the GC. Them myObject will be marked for deletion as well. As soon as all references to a given object disappear, the GC will eventually reclaim the memory.
There are (rare) exceptions, like event handling, where the dependency between two objects cannot be properly automatically ended, and you may end up with a memory leak: when you subscribe to an event on another class, then the subscriber cannot be collected even when there's no "direct" references to it. In that specific case, it might be interesting to clear the link manually.
是的,这就是 JVM 中垃圾收集器的目的。 JVM 可能会在稍后的某个时间调用对象的 Finalize 方法,然后它可能会丢弃关联的存储。
Yes, that is the purpose of the garbage collector in the JVM. The JVM may at some later time call the
finalize
method of the object, and then it may discard the associated storage.是的,有时将 Java 对象引用(指针)设置为 null 是个好主意。这可能(如果没有其他对该对象的引用)比其他情况更快地“释放”该对象。当您拥有由相互缠绕的对象组成的大型“网络”时,这尤其有用。
在最坏的情况下,您将花费一个额外的内存存储。
Yes, it's sometimes a GOOD idea to set Java object references (pointers) null. This may (if there are no other references to the object) "free" the object sooner than would otherwise occur. This is especially helpful when you have large "networks" of intertwined objects.
At worst case, you're costing one additional memory store.
是的,当满足以下条件时,引用指向的对象有资格进行垃圾回收(如果没有其他活动对该对象的引用):
Yes, The object the reference pointed to is eligible for garbage collection (if there are no other live references to the object) when: