让我们考虑以下2个循环引用示例:
直接循环引用
class A {
B b;
}
class B {
A a;
}
class A {
B b;
}
class B {
WeakReference<A> aRef;
}
SO question回答的以下@Jon Skeet清楚地表明,只要没有来自已知根的“GC行走”存在于循环中,直接的示例也将被垃圾收集。
我的问题如下:
是否有任何理由表现或以其他方式使用或不使用示例2中表示的习语 - 使用WeakReference的习语?
答案 0 :(得分:7)
是否有任何理由表现或以其他方式使用或不使用示例2中表示的习语
Java Reference
类型有几个性能影响:
他们比常规参考使用更多空间。
对于垃圾收集器而言,它们比普通引用要多得多。
我还认为它们会导致对象集合被一个或多个GC循环延迟......取决于GC的实现。
此外,应用程序必须处理WeakReference
可能被破坏的可能性
相比之下,正常循环引用没有性能或空间开销,因为在第一个示例中使用它们。
总之,你的弱参考习语会降低性能并增加程序的复杂性......没有任何实际的好处,我可以看到。
我的猜测是这个问题来源于错误的概念,即循环引用比Java中的非循环引用更昂贵......或者它们在某种程度上是有问题的。 (还有什么其他合乎逻辑的理由会导致人们提出像这样的“成语”?)事实上,事实并非如此。 Java垃圾收集器不会受到引用计数问题的困扰;例如C ++“智能指针”。循环引用被正确处理(即没有泄漏内存)并且在Java中有效处理。
答案 1 :(得分:1)
问题是你不知道GC什么时候会清除弱引用对象。
它可能会在您声明时清除! GC非常渴望收集它。
或者你可以对weakreference对象进行root引用,以防止它被垃圾回收。
或通过RegisteredQueue检查其状态。
这就像finalize方法。您不知道GC何时会执行此方法。
来源:
http://pawlan.com/monica/articles/refobjs/ http://docs.oracle.com/javase/7/docs/api/java/lang/ref/WeakReference.html