当前位置:  开发笔记 > 编程语言 > 正文

交叉引用和垃圾收集

如何解决《交叉引用和垃圾收集》经验,为你挑选了1个好方法。

有一个带有广泛对象图的应用程序.该图主要由一组子图组成,这些子图通过唯一的参考连接到图的其余部分.但在内部,每个这样的子图在对象之间都有一些交叉引用.偶尔这样的子图需要被抛弃.仅仅将指向该子图的唯一引用设置为null以使其符合垃圾收集的条件是否足够?

我担心的是内部交叉引用可能会"保护"整个子图从垃圾收集.换句话说,垃圾收集器是否足够明智,可以确定子图中的所有引用都不会离开子图的边界,因此可以清除整个子图.



1> VonC..:

如本SO问题所述,循环引用管理良好.

Java不进行引用计数,它确实使用跟踪垃圾收集(例如标记和扫描,复制集合或其某种组合).如果跟随所有活动引用以找出哪些对象是"可到达的",那么它将清除所有其他对象.

对象中的引用本身不可访问不会影响可访问性,因此它们是否为null无关紧要.

关于唯一一种情况,其中设置对null的引用可能会产生重大影响,即在长时间运行的方法中丢弃一个非常大的对象.

在这种情况下,将null设置为图形的引用将有助于形成隔离岛(即使对于内部循环引用),如本文所述.

您将在The Truth About Garbage Collection中找到有关无法访问状态的更多详细信息:

无法访问

当对象不再存在强引用时,对象进入无法访问状态.
当对象无法访问时,它是收集的候选对象.

请注意措辞:
仅仅因为对象是收集的候选者并不意味着它将立即被收集.JVM可以自由地延迟收集,直到对象立即需要使用内存.

重要的是要注意,不仅任何强引用都会在内存中保存一个对象.这些必须是从垃圾收集根链接的引用.GC根是一类特殊的变量,包括:

堆栈上的临时变量(任何线程)

静态变量(来自任何类)

来自JNI本机代码的特殊参考

循环强引用不一定会导致内存泄漏.考虑创建两个对象的代码,并将它们分配给彼此.

public void buidDog() {
   Dog newDog = new Dog();
   Tail newTail = new Tail();
   newDog.tail = newTail;
   newTail.dog = newDog;
}

在方法返回之前,方法中的临时堆栈变量有强引用,buildDog指向DogTail.

在之后buildDog方法返回时,DogTail都成为从根本无法访问,并收集候选人(虽然VM可能没有实际收集这些物品进行无限期量).

推荐阅读
女女的家_747
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有