将变量设置为null只清除引用吗?

9
如果我执行以下操作会发生什么情况:
Object obj = new Object();
obj = null;

它会从内存中删除对象,还是只清除引用?

更正式地说,考虑以下代码:

Object obj = new Object();
Object temp = obj;
obj = null;

为什么temp仍然不是null? 它不应该已经被从内存中删除了吗?


3
简短回答:objtemp不是对象。它们是可能指向对象的引用。 - Andy Thomas
7个回答

22

在您的第一个示例中:

             +------+
obj -------> |OBJECT|
             +------+

obj设置为null后:

             +------+
obj          |OBJECT|
             +------+

由于没有任何关于该对象的引用,因此它已变得无法访问,也就是说它“不存在”了。


在您的第二个示例中:

obj -------> +------+
             |OBJECT|
temp ------> +------+

obj设置为null后:

obj          +------+
             |OBJECT|
temp ------> +------+

你可以看到,temp 仍然引用着这个对象,因此它仍然“存在”。


3
Object obj = new Object();
obj = null;

上面的代码只是移除了引用,而没有删除对象。然而,由于没有其他对该对象的引用,垃圾回收器会清除该对象从内存中释放掉。
在这个例子中:
Object obj = new Object();
Object temp = obj;
obj = null;

temp仍然是对象的引用,因此对象仍然存储在内存中。


3
将一个对象设置为null,即清除了其引用。如果对象不再有任何引用,例如第一个例子,当JVM下次运行GC(垃圾回收器)时,内存可以被释放。只要对象仍然有引用(第二个例子),就无法释放内存。
此外,释放内存的GC和将内存返回给操作系统以便重用之间存在差异。通常,JVM会保留一次分配的内存,直到JVM不存在或OS没有可用的空闲内存。

2

Java使用垃圾回收机制,因此您永远不会知道对象何时从内存中删除。当您删除对对象的最后一个引用时,它将被传递给垃圾收集器,而垃圾收集器有时会删除该对象。

在您的第二个示例中,您创建了一个对象并将引用传递给obj。然后您通过temp引用obj。现在您有两个对对象的引用:obj和temp。当您删除obj引用时,该对象仍由temp引用,因此它不会被传递给垃圾收集器。


2
在你的第一个例子中,obj立即变得可以被垃圾回收。它尚未从内存中删除,尝试使用该引用将导致NullPointerException
在你的第二个例子中,对temp的赋值创建了一个最初由obj引用的副本。将obj设置为null不会使对象能够进行垃圾回收,因此它仍然存在。

1
这并不意味着对象从内存中被删除,只是引用已被设置为null。在Java中,垃圾回收器(GC)仅在需要更多内存或进行例行检查时才运行。在此之前,对象仍然存在于堆内存中。
由于Java没有指针和析构函数,因此堆存储完全由GC维护。

0

这两段代码的行为不同。

在前者中,由new Object()创建的对象引用将会被垃圾回收。而在后者中,由new Object()创建的对象引用不会被垃圾回收,因为它仍然被temp引用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接