如果我这样做会发生什么:
Object obj = new Object();
obj = null;
它是从内存中删除对象,还是只清除引用?
更正式地,考虑代码:
Object obj = new Object();
Object temp = obj;
obj = null;
为什么temp
仍然不是null
?难道它不能从内存中删除吗?
答案 0 :(得分:14)
在你的第一个例子中:
obj -------> |OBJECT|
将obj
设置为null
后:
obj |OBJECT|
不存在对该对象的引用,因此它“不存在”,因为它已无法访问。
在你的第二个例子中:
obj -------> | |
|OBJECT|
temp ------> | |
将obj
设置为null
后:
obj | |
|OBJECT|
temp ------> | |
您可以看到temp
仍引用该对象,因此它仍然“存在”。
答案 1 :(得分:3)
将对象设置为null,清除引用。如果不再引用该对象,如第一个示例所示,当JVM下次运行GC(Grarbage Collector)时,可以释放内存。
只要仍然存在对象的引用(第二个示例),就不会发生这种情况。
此外,通过GC释放内存并将内存返回到操作系统之间存在差异,因此可以重复使用。通常,JVM会保留一次分配的内存,直到JVM存在或操作系统的可用内存不足为止。
答案 2 :(得分:3)
Object obj = new Object();
obj = null;
上图:它只删除引用,不删除对象。但是,GC将从内存中清除对象,因为没有对该对象的其他引用。
在此:
Object obj = new Object();
Object temp = obj;
obj = null;
temp仍然是对象的引用,因此对象保留在内存中。
答案 3 :(得分:2)
Java与垃圾收集一起使用。因此,您永远不会知道从内存中删除对象的时间。删除对象的最后一个引用时,它将被传递给垃圾收集器,垃圾收集器有时会删除该对象。
在第二个示例中,您将创建一个对象并提供对obj的引用。然后你用temp引用obj。现在您有2个对象的引用。 obj和temp。当你现在删除引用obj时,对象仍然被temp引用,所以它不会被赋予垃圾收集器。
答案 4 :(得分:2)
在您的第一个示例中,C2264
立即符合垃圾回收条件。它尚未从内存中删除,尝试使用该引用将导致obj
。
在您的第二个示例中,分配给NullPointerException
creates a copy of the reference originally referred to by obj
。将temp
设置为obj
不会使该对象符合垃圾回收的条件,因此它仍然存在。
答案 5 :(得分:1)
如果引用已设置为null,则不会从内存中删除它。在java GC(垃圾收集器)中,只有在需要更多内存或例行检查时才以特定持续时间运行。在那之前,对象仍然存在于HEAP内存中。
由于JAVA没有指针和析构函数,HEAP存储由GC完全维护。
答案 6 :(得分:0)
这两段代码表现不同。
在前者中,new Object()
创建的对象引用将符合GC的条件。在后者中,由new Object()
创建的对象引用不符合GC条件,因为它仍由temp
引用。