在new A()
后,我们会分配足够的内存来容纳A
包含的所有对象。
对象A()
可能包含其他对象,例如B()
和C()
问题1:当不再需要A()
并且您想要将其从堆中删除时,是否会将其设置为null
? (如果没有,那么用JVM
GC
此对象现在发出信号的正确方法是什么?)
问题2:如果是这样,指向B()
和C()
的实例会发生什么
问题3:有没有办法可以观察到这种效果? (释放内存以释放对象)
答案 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)
如果您有B
和C
的实时引用,那么它就不会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)
如果将其设置为null,那么它是GC
在需要内存时释放内存的信号。但只有在没有更多实例引用该对象时才会发生这种情况。
如果仍然存在引用对象的实例,则在完全没有引用该对象的实例之前,它不会进行GC编辑。因此,只有当A()是引用它们的唯一者时,B()和C()才会被GC编辑。
使用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时调用。