垃圾收集 - 孤立的LinkedList链接

tsk*_*zzy 12 java garbage-collection linked-list

假设你有参考A -> B -> C -> D.当您删除对Bfrom 的引用时A,您将留下一个孤立的对象链B -> C -> D.

CD被垃圾收集,即使没有办法让他们(因为有没有参考B)?

我认为GC对此很聪明,并将解决任何此类依赖关系.

但是,我查看了该课程的源代码LinkedList,发现了与此信念相反的内容.我注意到,当列表被clear()编辑时,每个链接的所有引用都被显式设置为null,从而使其成为一个O(n)操作.这样做有什么理由/好处吗?

Ste*_*n C 11

这确实看起来有点奇怪.也许明确拆解列表的原因是清除现有迭代器和子列表以及父列表的列表.

肯定没有做更快的垃圾收集.垃圾收集器不会遍历无法访问的对象中的引用,因此将它们置零将不会有任何区别.

UPDATE

该方法的更新版本具有以下注释:

// Clearing all of the links between nodes is "unnecessary", but:
// - helps a generational GC if the discarded nodes inhabit
//   more than one generation
// - is sure to free memory even if there is a reachable Iterator
Run Code Online (Sandbox Code Playgroud)

因此,至少在某些情况下,似乎GC有一个好处.

假设Node在较老一代中的a包含对Node年轻一代中的对象(例如,元素或元素)的引用.当收集年轻一代时,该引用成为"根",导致保留年轻代对象,即使老一代Node无法访问.这种状态持续到收集老一代.老一代很少被收集.

如果遍历列表并将其拆除,则会为包含旧 - >新引用的变量分配一个null.该分配的写屏障导致(立即或在GC时间)原始引用不再是"根".因此,现在可以收集年轻一代中的对象,并且它不会最终"老化"给老一代(这提出了需要收集该代的时间).

据推测,GC的好处超过了取消列表的成本...平均而言,或者在成本是灾难性的情况下.

有关更多信息,请参阅Jones和Lins的"用于动态内存管理的垃圾收集算法".它在我的(第一版)副本的第7.5章中.


一般来说,抛弃一个Collection物体并重新开始比清除它以便重复使用更好.