Asked  7 Months ago    Answers:  5   Viewed   41 times

From my understanding, garbage collection in Java cleans up some objects if nothing else is 'pointing' to that object.

My question is, what happens if we have something like this:

class Node {
    public object value;
    public Node next;
    public Node(object o, Node n) { value = 0; next = n;}
}

//...some code
{
    Node a = new Node("a", null), 
         b = new Node("b", a), 
         c = new Node("c", b);
    a.next = c;
} //end of scope
//...other code

a, b, and c should be garbage collected, but they are all being referenced by other objects.

How does the Java garbage collection deal with this? (or is it simply a memory drain?)

 Answers

55

Java's GC considers objects "garbage" if they aren't reachable through a chain starting at a garbage collection root, so these objects will be collected. Even though objects may point to each other to form a cycle, they're still garbage if they're cut off from the root.

See the section on unreachable objects in Appendix A: The Truth About Garbage Collection in Java Platform Performance: Strategies and Tactics for the gory details.

Tuesday, June 1, 2021
 
pinaki
answered 7 Months ago
37

GarbageCollectorMBean.getCollectionTime() return cumulative wall clock time in milliseconds for specific algorithm.

For Stop-the-World algorithms (young collections usually) this could be interpreted as time application was paused.

For concurrent algorithms that value is perty useless, because it is not STW time and it is not CPU time (algorithm may use multiple threads, but wall clock time would be calculated).

Correct CPU time consumed by GC algorithm could be retrieved from performance counters (here is example of code reading these counters).

Thursday, August 5, 2021
 
Mountains
answered 4 Months ago
78

I think I found the answer I'm looking for in some links provided by @SvenMarnich in comments to the original question:

Container objects are Python objects that can hold references to other Python objects. Lists, Classes, Tuples etc are container objects; Integers, Strings etc. are not. So, only container objects are at risk for being in a circular reference.

Each Python object has a field - *gc_ref*, which is (I believe) set to NULL for non-container objects. For container objects it is set equal to the number of non container objects that reference it

Any container object with a *gc_ref* count greater than 1 (? I would've thought 0, but OK for now ?) has references that are not container objects. So they are reachable and are removed from consideration of being unreachable memory islands.

Any container object reachable by an object known to be reachable (i.e. those we just recognized as having a *gc_ref* count greater than 1) also does not need to be freed.

The remaining container objects are not reachable (except by each other) and should be freed.

http://www.arctrix.com/nas/python/gc/ is a link providing a fuller explanation http://hg.python.org/cpython/file/2059910e7d76/Modules/gcmodule.c is a link to the source code, which has comments further explaining the thoughts behind the circular reference detection

Monday, September 6, 2021
 
lechup
answered 3 Months ago
11

The last two lines do not help.

  • Once the list variable goes out of scope*, if that's the last reference to the linked list then the list becomes eligible for garbage collection. Setting list to null immediately beforehand adds no value.

  • Once the list becomes eligible for garbage collection, so to do its elements if the list holds the only references to them. Clearing the list is unnecessary.

For the most part you can trust the garbage collector to do its job and do not need to "help" it.

* Pedantically speaking, it's not scope that controls garbage collection, but reachability. Reachability isn't easy to sum up in one sentence. See this Q&A for an explanation of this distinction.


One common exception to this rule is if you have code that will retain references longer than they're needed. The canonical example of this is with listeners. If you add a listener to some component, and later on that listener is no longer needed, you need to explicitly remove it. If you don't, that listener can inhibit garbage collection of both itself and of the objects it has references to.

Let's say I added a listener to a button like so:

button.addListener(event -> label.setText("clicked!"));

Then later on the label is removed, but the button remains.

window.removeChild(label);

This is a problem because the button has a reference to the listener and the listener has a reference to the label. The label can't be garbage collected even though it's no longer visible on screen.

This is a time to take action and get on the GC's good side. I need to remember the listener when I add it...

Listener listener = event -> label.setText("clicked!");
button.addListener(listener);

...so that I can remove it when I'm done with the label:

window.removeChild(label);
button.removeListener(listener);
Saturday, October 16, 2021
 
Willy
answered 2 Months ago
51

There's set of "root objects" which are considered always accessible: e.g., Thread references, static variables, class references. If some object can not be reached via link of references from these root objects, it considered to be available for GC, even if there are some references to that object.

Wednesday, November 17, 2021
 
pppggg
answered 2 Weeks ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share