16

假设我有一个对引擎有普通(强)引用的汽车的弱引用。不存在对汽车或发动机的其他参考。引擎可以被垃圾收集吗?

4

3 回答 3

18

是的,它可以,这正是弱引用的设计方式。弱引用是您的对象对应用程序的根,即使该对象可能有其他强引用,但重要的是引用,并且由于根引用是弱引用,因此该对象将成为垃圾回收的候选对象。

有关更多信息,请参阅WeakReference类文档:

弱引用对象,不会阻止它们的引用对象被最终化、最终化,然后被回收。弱引用最常用于实现规范化映射。

假设垃圾收集器在某个时间点确定一个对象是弱可达的。那时,它将原子地清除对该对象的所有弱引用以及对通过强引用和软引用链可以访问该对象的任何其他弱可达对象的所有弱引用。同时它将声明所有以前的弱可达对象都是可终结的。在同一时间或稍后的某个时间,它会将那些在引用队列中注册的新清除的弱引用排入队列。

仅供参考,WeakReferenceJava 提供了另外两个子类Reference:SoftReferencePhantomReference.

于 2010-04-06T12:22:38.487 回答
8

Car 实例可能会被垃圾回收,但不能保证它在下一个 GC 周期被垃圾回收,甚至根本不会被回收。例如,

  • 在 GC 运行之前的某个时间,应用程序可以调用并保存对getin (例如)某个可达对象的属性的引用。然后该实例变得完全可访问并且不再有资格进行垃圾收集。WeakReferenceCarCar

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

  • 即使 GC 中断了Car对 WeakReference 中的引用,Car也不会立即回收该实例。相反,现在无法访问的回收Car可能会在以后的 GC 周期中发生(在可能的最终确定之后)。

于 2010-04-06T13:01:55.843 回答
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());
    }

}
于 2010-04-06T12:30:47.673 回答