关于Java垃圾收集,需要澄清

时间:2012-06-11 16:03:21

标签: java garbage-collection

new A()后,我们会分配足够的内存来容纳A包含的所有对象。

对象A()可能包含其他对象,例如B()C()

问题1:当不再需要A()并且您想要将其从堆中删除时,是否会将其设置为null? (如果没有,那么用JVM GC此对象现在发出信号的正确方法是什么?)

问题2:如果是这样,指向B()C()的实例会发生什么

问题3:有没有办法可以观察到这种效果? (释放内存以释放对象)

7 个答案:

答案 0 :(得分:5)

将A设置为null会将A标记为GC要释放的候选项。如果对这些实例的唯一引用来自实例A,则也会标记B和C的实例。

编辑问题3:调试此效果的一种简单方法是使用方法finalize;当一个对象被GC时,他的finalize被调用。

但是,请注意此方法:不保证始终执行finalize(因为GC不能保证释放对象),并且绝不应该用于应用程序的一般用途。

根据您的IDE,有更好的调试工具。例如,在eclipse中:http://www.yourkit.com/docs/80/help/garbage_collection.jsp

答案 1 :(得分:3)

如果您有BC的实时引用,那么它就不会GCed

如果任何对象没有实时引用,那么该对象就可以被GCed

class A{
 B b = new B();
 C c = new C();
}

现在当你做

A a = new A();
a= null;//instance referred by a,b & c are ready to be collected in this system

答案 2 :(得分:2)

  

对象A()可能包含其他对象,如B()和C()

对象仅包含对其他对象的基元和引用。

  

问题1:当不再需要A()而你想将它从堆中删除时,将它的引用设置为null可以做到这一点吗?

很少需要,但你可以这样做。

  

问题2:如果是这样,指向B()和C()

的实例会发生什么

没什么,它们是不相关的物体。

  

问题3:有没有办法可以观察到这种效果? (释放内存以释放对象)

您可以覆盖finalize()方法或使用ReferenceQueues。这只会告知您收集的对象而不是丢弃对象。最好避免这样做。


没有来自根上下文的强引用的对象,例如线程堆栈,可以收集。这怎么会发生并不重要。将引用设置为null可以允许这种情况发生,但更常见的是允许变量超出范围是丢弃对象的更简单方法。

如果你有对象B,它指向C指向B并且没有其他对这些对象的引用,即使有对这些对象的引用,它们仍然会被清理。

答案 3 :(得分:1)

您无法强制GC删除对象。 GC将自动删除任何可安全删除的对象。您可以通过调用System.gc()强制GC运行,这将删除它可以的任何对象。

仅当没有对该对象的其他引用时,

A = null才会删除该对象。

一般情况下,GC存在,因此您不必担心删除和内存收集。如果一个东西可以安全删除,它最终会被删除。

如果B()停止指向它们,则会删除

C()A,并且A是首先指向它们的唯一内容。

答案 4 :(得分:1)

  1. 如果将其设置为null,那么它是GC在需要内存时释放内存的信号。但只有在没有更多实例引用该对象时才会发生这种情况。

  2. 如果仍然存在引用对象的实例,则在完全没有引用该对象的实例之前,它不会进行GC编辑。因此,只有当A()是引用它们的唯一者时,B()和C()才会被GC编辑。

  3. 使用Java通过扫描仪读取大文本文件(约3mb),然后关闭并丢弃扫描仪,并在完成后调用System.gc(),可以很容易地观察到这种效果。

答案 5 :(得分:1)

如果取消对A的所有引用,并且如果没有其他对B和C的实时引用,那么当GC运行时,这些引用也将被GC。

调用System.gc()并不能保证gc会立即运行。它可能会也可能不会运行,根本无法保证。

And There is no guaranteed way to force gc run immediately as you request it.

是的,你可以看到效果,因为gc运行释放内存。

要查看关于堆/内存使用情况的可视化图表/信息...,您可以使用jdk工具,在以下位置找到它的窗口:

JAVA_HOME\bin\jconsole.exe 

答案 6 :(得分:1)

它是规则的缩影,that when an object has NO reference attached to it, its a toast for the Garbage collector to eat.

标记一个null将为A做一个祝酒词。如果指向A的引用是唯一引用B和C的引用,则这两个引用都是垃圾收集的候选者

finalize是对象类方法,在对象为Garbage Collected时调用。