本文介绍了垃圾回收 - 孤立的LinkedList链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设你有引用 A - > B - > C - > d 。当您从 A 删除对 B 的引用时,您将剩下一个孤立的对象链 B - > C - > D 。



C 和 D 被垃圾收集,即使没有办法到达它们(因为没有引用 B )?



我想像GC很聪明,并且会解决任何这样的依赖关系。

然而,我看了一下为 LinkedList 类,并发现与此信念相悖的东西。我注意到,当一个列表是 clear() ed时,对每个链接的所有引用都显式设置为 null ,从而使它成为 O(n)操作。这样做是否有任何理由/好处?解析方案

这看起来有点奇怪。也许它明确拆除列表的原因是为了清除现有迭代器和子列表以及父列表中的列表。



这当然不是为了使垃圾收集更快。垃圾收集器不会遍历无法访问的对象中的引用,因此将它们置为空也无济于事。



UPDATE



该方法的最新版本包含以下评论:

  //清除节点之间的所有链接都是不必要的,但是:
// - 如果被丢弃的节点居住在
//多于一代
// - 则有助于代GC内存,即使有可达的迭代器

因此,看起来GC有一个好处,至少在某些情况下。假设旧版本中的 Node 包含对对象的引用(例如 Node 或一个元素)在年轻一代。即使旧一代 Node 无法访问,该参照在收集年轻一代时也成为根,导致年轻一代对象被保留。这种状态一直持续到老一代被收集。如果您遍历列表并拆除它,那么包含旧 - >新引用的变量将被赋予一个 null / code>。该分配的写入屏障(立即或在GC时间)导致原始引用不再是根。因此,年轻一代的目标现在可以被收集起来,并且不会结束老化到老一代(这提出了需要收集这一代人的时间)。

据推测,GC的收益大于取消清单的成本......无论是平均成本还是成本都是灾难性的。


有关更多信息,请参阅Jones和Lins的用于动态内存管理的垃圾收集算法。这是在我的(第一版)7.5复制。






一般来说,最好扔一个 Collection 对象并重新开始,而不是清除它以便重用。


Suppose you have references A -> B -> C -> D. When you delete the reference to B from A, you're left with an orphaned chain of Objects B -> C -> D.

Will C and D be garbage collected even though there's no way to get to them (since there's no reference to B)?

I imagine the GC is smart about this and will resolve any such dependencies.

However, I took a look into the source code for the LinkedList class and found something contrary to this belief. I noticed that when a list is clear()ed, all of the references to each link are explicitly set to null, thus making it an O(n) operation. Is there any reason/benefit for doing so?

解决方案

That does look a bit peculiar. Maybe the reason that it is explicitly dismantling the list is so that the list is cleared for existing iterators and sublists as well as the parent list.

It is certainly NOT done to make the garbage collection faster. A garbage collector doesn't traverse the references in an unreachable object, so nulling them won't make any difference.

UPDATE

A more recent version of the method has these comments:

// 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

So, it appears that there is an benefit for the GC, at least in some cases.

Suppose that a Node in an older generation contains a reference to an object (e.g. a Node or an element) in a younger generation. That reference becomes a "root" when collecting of the younger generation, causing the young generation object to be retained, even if the old generation Node is unreachable. This state continues until the older generation is collected. Old generations are collected infrequently.

If you traverse the list and dismantle it, the variable containing the old -> new reference is assigned a null. The write-barrier for that assignment causes (immediately or at GC time) the original reference to no longer be a "root". Thus, the object in the younger generation can now be collected, and it doesn't end up "tenured" to an older generation (which brings forward the time when that generation needs to be collected).

Presumably, the GC benefits outweigh the cost of unpicking the list ... either on average, or in cases where the costs are disastrous.

For more information, refer to "Garbage Collection algorithms for dynamic memory management" by Jones and Lins. It is in chapter 7.5 in my (first edition) copy.


Generally speaking, it is better to throw a Collection object away and start again than it is to clear it for reuse.

这篇关于垃圾回收 - 孤立的LinkedList链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 19:06