简体   繁体   English

交叉引用和垃圾收集

[英]Cross-references and garbage collection

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? 仅仅将指向该子图的唯一引用设置为null以使其符合垃圾收集的条件是否足够?

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. 换句话说,垃圾收集器是否足够明智,可以确定子图中的所有引用都不会离开子图的边界,因此可以清除整个子图。

As stated in this SO question , circular reference is well managed. 如本SO问题所述 ,循环引用管理良好。

Java does not do reference counting, it does uses tracing garbage collection (for example mark-and-sweep, copying collection or a some combination thereof). Java不进行引用计数,它确实使用跟踪垃圾收集 (例如标记和扫描,复制集合或其某种组合)。 If follows all the active references to find out what objects are "reachable" and then it cleans up everything else. 如果跟随所有活动引用以找出哪些对象是“可到达的”,那么它将清除所有其他对象。

References in objects not themselves reachable don't affect reachability so it doesn't matter if they are null or not. 对象中的引用本身不可访问不会影响可访问性,因此它们是否为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. 关于唯一一种情况,其中设置对null的引用可能会产生重大影响,即在长时间运行的方法中丢弃一个非常大的对象。

In that case, setting null to the reference of the graph will help making an island of isolation (even for internal circular references) as described in this article . 在这种情况下,将null设置为图形的引用将有助于形成隔离岛 (即使对于内部循环引用),如本文所述

You will find more details about the unreachable state in The Truth About Garbage Collection : 您将在The Truth About Garbage Collection中找到有关无法访问状态的更多详细信息:

Unreachable 无法访问

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. 当对象无法访问时,它是收集的候选对象。

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. JVM可以自由地延迟收集,直到对象立即需要使用内存。

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: GC根是一类特殊的变量,包括:

  • Temporary variables on the stack (of any thread) 堆栈上的临时变量(任何线程)
  • Static variables (from any class) 静态变量(来自任何类)
  • Special references from JNI native code 来自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;
}

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方法中的临时堆栈变量有强引用,指向DogTail

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). buildDog方法返回之后, DogTail都无法从根目录中访问,并且是收集的候选者(尽管VM可能无法在无限期的时间内实际收集这些对象)。

是的 - 垃圾收集器可以处理循环引用等。

The JVM operates on the notion of "islands of unreachability". JVM的运作理念是“不可达的岛屿”。 If there is an unreachable 'island' of interconnected objects then that set of objects is eligible for garbage collection in its entirety. 如果存在互连对象的无法到达的“孤岛”,那么该对象集合完全可以进行垃圾收集。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM