假设我对一辆普通(强力)引擎的汽车有一个弱引用。没有其他对汽车或发动机的引用。发动机可以收集垃圾吗?
答案 0 :(得分:18)
是的,这正是weak references的设计工作方式。弱引用是对象对应用程序的根,即使对象可能有其他强引用,但重要的是 root 引用,因为根引用是弱引用,对象将是垃圾收集的候选人。
有关详细信息,请参阅WeakReference
课程文档:
弱引用对象,但没有 防止他们的指涉 最终确定,最终确定,然后 回收。弱参考是最多的 通常用于实现规范化 映射。
假设垃圾收集器在某个时间点确定 一个对象是弱可达的。在 那个时候它会原子地清除所有 对该对象和所有对象的弱引用 对任何其他人的弱引用 弱可达物体 该对象可以通过 强大而柔软的链条 引用。与此同时 将宣布所有以前的 弱可达物体 终结。在同一时间或在 一些晚些时候它将排队 新近清除的弱引用 在参考队列中注册。
仅供参考,与WeakReference
一起,Java提供了Reference
的另外两个子类:SoftReference
和PhantomReference
。
答案 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());
}
}