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.
Cross references are document elements that point to a different element in the same document. For example, a cross reference can point to a different page in the document (e.g. “see page 13”), to a footnote (e.g. “see note 2 on page 13”) or to a specific heading (e.g. “see heading 3.1: The Hobbit”), among others.
Reference counting garbage collection is where each object has a count of the number of references to it. Garbage is identified by having a reference count of zero. An object's reference count is incremented when a reference to it is created, and decremented when a reference is destroyed.
The . NET garbage collector can absolutely handle circular references.
To handle the problem of circular references in C#, you should use garbage collection. It detects and collects circular references. The garbage collector begins with local and static and it marks each object that can be reached through their children. Through this, you can handle the issues with circular references.
As stated in this SO question, circular reference is well managed.
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.
References in objects not themselves reachable don't affect reachability so it doesn't matter if they are null or not.
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.
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.
You will find more details about the unreachable state in 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.
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:
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
.
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).
Yes - the garbage collector can cope with circular references etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With