【发布时间】:2010-04-06 12:20:02
【问题描述】:
假设我对具有普通(强)引擎引用的汽车有一个弱引用。不存在对汽车或发动机的其他参考。引擎可以被垃圾回收吗?
【问题讨论】:
标签: java garbage-collection weak-references
假设我对具有普通(强)引擎引用的汽车有一个弱引用。不存在对汽车或发动机的其他参考。引擎可以被垃圾回收吗?
【问题讨论】:
标签: java garbage-collection weak-references
是的,这正是weak references 的工作原理。弱引用是您的对象对应用程序的根,即使对象可能有其他强引用,重要的是 root 引用,并且由于根引用是弱引用,因此对象将是垃圾收集的候选者。
更多信息请查看WeakReference类文档:
弱引用对象,不 防止他们的参照物 最终化,最终化,然后 回收。弱引用是最多的 常用于实现规范化 映射。
假设垃圾收集器在某个时间点确定 一个对象是弱可达的。在 到时候它会原子地清除所有 对该对象的弱引用和所有 对任何其他的弱引用 弱可达对象 该对象可以通过 强软链 参考。同时它 将宣布所有以前的 弱可达对象 可最终确定的。同时或在 稍后它会将那些 新清除的弱引用是 使用参考队列注册。
仅供参考,除了 WeakReference,Java 还提供了 Reference 的另外两个子类:SoftReference 和 PhantomReference。
【讨论】:
Car 实例可以被垃圾回收,但不能保证它将在下一个 GC 周期被垃圾回收,甚至不保证它会在全部。例如,
在 GC 运行之前的某个时间,应用程序可以在 WeakReference 上调用 get 并将对 Car 的引用保存在(例如)某个可达对象的属性中。 Car 实例随后变得完全可访问,不再符合垃圾回收条件。
如果 GC 在所描述的状态下以Car 运行,则 JVM 规范不保证在下一个 GC 周期中会检测到弱可达。例如,如果给定的 GC 周期只收集最新一代(并且 Car 已提升为老一代),则 GC 不会确定它是弱可达的。
即使 GC 在 WeakReference 中中断对 Car 的引用,Car 实例也不会立即回收。相反,现在无法访问的Car 的回收可能会在稍后的 GC 周期中发生(在可能的最终确定之后)。
【讨论】:
这是一个演示弱引用的单元测试。请注意,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());
}
}
【讨论】:
WeakReference<T>的参数化,其中类型参数T是类Car。