Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cross-references and garbage collection

Tags:

java

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.

like image 529
Maxim Vladimirsky Avatar asked Nov 07 '08 08:11

Maxim Vladimirsky


People also ask

What is an example of cross-reference?

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.

What is reference counting and garbage collection?

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.

Can garbage collector release isolate circular references?

The . NET garbage collector can absolutely handle circular references.

How does garbage collector resolves circular reference issue?

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.


2 Answers

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:

  • Temporary variables on the stack (of any thread)
  • Static variables (from any class)
  • Special references from JNI native code

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).

like image 66
VonC Avatar answered Oct 26 '22 06:10

VonC


Yes - the garbage collector can cope with circular references etc.

like image 43
Jon Skeet Avatar answered Oct 26 '22 04:10

Jon Skeet