对包含嵌套强引用和垃圾收集的对象的弱引用

时间:2010-04-06 12:20:03

标签: java garbage-collection weak-references

假设我对一辆普通(强力)引擎的汽车有一个弱引用。没有其他对汽车或发动机的引用。发动机可以收集垃圾吗?

3 个答案:

答案 0 :(得分:18)

是的,这正是weak references的设计工作方式。弱引用是对象对应用程序的根,即使对象可能有其他强引用,但重要的是 root 引用,因为根引用是弱引用,对象将是垃圾收集的候选人。

有关详细信息,请参阅WeakReference课程文档:

  

弱引用对象,但没有   防止他们的指涉   最终确定,最终确定,然后   回收。弱参考是最多的   通常用于实现规范化   映射。

     

假设垃圾收集器在某个时间点确定   一个对象是弱可达的。在   那个时候它会原子地清除所有   对该对象和所有对象的弱引用   对任何其他人的弱引用   弱可达物体   该对象可以通过   强大而柔软的链条   引用。与此同时   将宣布所有以前的   弱可达物体   终结。在同一时间或在   一些晚些时候它将排队   新近清除的弱引用   在参考队列中注册。

仅供参考,与WeakReference一起,Java提供了Reference的另外两个子类:SoftReferencePhantomReference

答案 1 :(得分:8)

Car实例可能被垃圾收集,但无法保证在下一个GC周期中被垃圾收集,或者甚至会在所有。例如,

  • 在GC运行之前的某个时间,应用程序可以在get上调用WeakReference并将对Car的引用保存在某些属性中(例如)可达物体。然后,Car实例变得完全可访问,不再符合垃圾回收的条件。

  • 如果GC在所述状态下以Car运行,则JVM规范无法保证在下一个GC周期中检测到弱可达。例如,如果给定的GC周期仅收集最新一代(并且Car已被提升为老一代),则GC不会确定它是弱可达的。

  • 即使GC断开对WeakReference中Car的引用,也不会立即回收Car实例。相反,在稍后的GC循环中可能会发生现在无法到达的Car的回收(在可能的最终确定之后)。

答案 2 :(得分:1)

这是一个演示弱引用的单元测试。请注意,System.gc()不保证对象将被垃圾收集,您不应该依赖它。

import junit.framework.TestCase;

import java.lang.ref.WeakReference;

public class WeakReferenceTest extends TestCase {


    class Car {

        Engine engine = new Engine();

    }

    class Engine {

    }

    public void testWeakReferences() {
        WeakReference<Car> carRef = new WeakReference<Car>(new Car());
        assertNotNull(carRef.get());
        System.gc();
        assertNull(carRef.get());
    }

}