Java循环引用和垃圾回收

3
让我们考虑以下两个循环引用的例子:
直接的循环引用
class A {        
    B b;        
}

class B {
    A a;
}

弱引用

class A {
    B b;
}

class B {
    WeakReference<A> aRef;
}

以下由Jon Skeet(@Jon Skeet)回答的Stack Overflow问题说明,只要从已知的根到循环中不存在“GC walk”,直接的示例也将被垃圾回收。
我的问题是:
在性能或其他方面,使用或不使用示例2中表示的习惯用法——使用WeakReference是否有任何原因?

1
我不会让代码变得更加复杂或使用比必要更多的概念,而是问自己“我需要这样做的好理由是什么?”而不是说“为什么不呢?” - Peter Lawrey
@PeterLawrey,这正是我的问题:“是否有任何好的理由...?” 我的观点是要了解是否在循环、弱引用和GC方面我漏掉了什么。我当然不打算盲目地在所有情况下都使用示例#2。我想知道是否存在一种情况更可取,或者是否不存在... - Yaneeve
2个回答

7
是否有任何性能或其他原因来使用或不使用示例2中所代表的习语?
Java的引用类型有一些性能方面的影响:
- 它们比常规引用使用更多的空间。 - 它们对于垃圾收集器来说比普通引用更耗费资源。 - 我还相信,它们可以导致对象的收集被一个或多个GC周期延迟...这取决于GC实现。
此外,应用程序必须处理WeakReference可能会断开的可能性。
相比之下,在第一个示例中使用正常循环引用没有任何性能或空间开销。
总之,您的弱引用习惯降低了性能并增加了程序复杂性...我看不到任何实际的好处。
我的猜测是,这个问题源于在Java中循环引用比非循环引用更昂贵或者它们在某种程度上有问题的“错误”概念。(还有什么其他的逻辑原因会导致提出这样的“习语”呢?) 实际上,情况并非如此。 Java垃圾收集器不会受到引用计数的问题的困扰;例如:C ++“智能指针”。 在Java中,循环引用被正确(即无内存泄漏)且高效地处理。

1

你最后一句话应该是指“finalize”,而不是“finally”。 - Dawood ibn Kareem

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接