交叉引用和垃圾回收 [英] Cross-references and garbage collection

查看:62
本文介绍了交叉引用和垃圾回收的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个带有广泛对象图的应用程序.该图主要由一组子图组成,这些子图通过唯一的引用连接到该图的其余部分.但是在内部每个这样的子图在对象之间都有一定数量的交叉引用.偶尔需要丢弃此类子图.仅将指向该子图的唯一引用设置为null以使其有资格进行垃圾回收就足够了吗?

There is an application with an extensive object graph. This graph mainly consists of a set of subgraphs which are connected to the rest of the graph through the only reference. But internally each such subgraph has some number of cross-references among objects. Once in a while such a sub graph needs to be thrown away. Would it be enough just to set to null the only referece which points to that subgraph to make it eligible for garbage collection?

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

My concern is that internal cross-references may "protect" the entire subgraph from garbage collection. In other words, is the garbage collector wise enough to figure out that all references in a subgraph do not leave the boundaries of the subgraph and therefore entire subgraph can be purged.

推荐答案

SO问题,可以很好地管理循环引用.

As stated in this SO question, circular reference is well managed.

Java不进行引用计数,它使用跟踪垃圾收集(例如mark-扫描,复制集合或它们的某种组合).如果遵循所有活动的引用,以找出哪些对象是可到达的",则它将清除所有其他内容.

Java does not do reference counting, it does uses tracing garbage collection (for example mark-and-sweep, copying collection or a some combination thereof). If follows all the active references to find out what objects are "reachable" and then it cleans up everything else.

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

References in objects not themselves reachable don't affect reachability so it doesn't matter if they are null or not.

可以想到,关于将null设置为null的唯一情况可能会产生重大影响,那就是在长时间运行的方法中间丢弃非常大的对象.

About the only case in which setting a reference to null might, conceivably, have a significant effect is in discarding a very large object in the middle of a long running method.

在这种情况下,如本您将在关于垃圾收集的真相:

无法访问

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

An object enters an unreachable state when no more strong references to it exist.
When an object is unreachable, it is a candidate for collection.

请注意以下措辞:
仅仅因为对象是收集对象并不意味着它会立即集.JVM可以自由地延迟收集,直到立即需要对象消耗主题为止.

Note the wording:
Just because an object is a candidate for collection doesn’t mean it will be immediately collected. The JVM is free to delay collection until there is an immediate need for thememory being consumed by the object.

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

It’s important to note that not just any strong reference will hold an object in memory. These must be references that chain from a garbage collection root. GC roots are a special class of variable that includes:

  • (任何线程)堆栈上的临时变量
  • 静态变量(来自任何类)
  • 来自JNI本机代码的特殊引用

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

Circular strong references don’t necessarily cause memory leaks. Consider a code creating two objects, and assigns them references to each other.

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

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

Before the method returns, there are strong references from the temporary stack variables in the buildDog method pointing to both the Dog and the Tail.

buildDog 方法返回后, Dog Tail 都无法从根访问,并且可以作为收集对象(尽管虚拟机可能实际上不会无限期地收集这些对象.

After the buildDog method returns, the Dog and Tail both become unreachable from a root and are candidates for collection (although the VM might not actually collect these objects for an indefinite amount of time).

这篇关于交叉引用和垃圾回收的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆