How does java GC clean inter related object - java

Could anyone please tell me what will be with objects that refer to each other? How does java's GC resolve that issue? Thanks in advance!

If you have object A and B, and if the following conditions hold:
A references to B
B references to A
No other objects reference to any one of them
They are not root objects (e.g. objects in the constants pool etc)
then, these two objects will be garbage collected. This is called "circular reference".
This is because the mark-and-sweep GC will scan and find out all the objects that are reachable from the root objects. If A and B reference each other without any external reference, the mark-and-sweep GC won't be able to mark them as reachable, hence will be selected as candidates for GC.
There are a number of different mark-and-sweep implementations (naive mark-and-sweep, tri-colour etc). But the fundamental idea is the same. If an object cannot be reached from the root by direct/indirect references, it will be garbage collected.

There is a number of GCs. In the Young Generation, there is a copy collector.
What this does is find all the objects which are referenced from "root" objects such a thread stacks. e.g. the eden space is copied to a survivor space, and the survivor spaces are copied to each other. Anything left uncopied is cleared away.
This means if you have a bundle of objects which refer to each other and there is no strong reference to any of them, they will be discarded on the next collection. (The exception being soft references where the GC can choose to keep them or not)

Related

Garbage collection of List items

I have a Java ArrayList with references to other objects stored within the List.
If I mark the List as null then when it is garbage collected, will all the stored items in it also get claimed by GC (assuming there are no other references to them)?
thanks,
Jakao
If you know it (can access it from code / have a reference to it anywhere) it´s there (and won´t ever be collected), if you don´t it might be gone. When is it gone? None of your concern, that´s the point of having a garbage collector.
Assuming there are no other references to them, they will be GC.
In java object reference is an abstract concept, you should not worry about how the JVM manages object storage, but if you interested in memory managment in java, I suggest you deepen the arguments of the weak and soft reference and memory pools.

Collecting old objects from java heap

I have Order_Item class instance, and these are paths to GC Roots (excluding phantom/weak/soft references):
I have few questions:
1) I'm not sure if the Order_Item will be garbage collected.
I tried to run System.gc(), and the object remained in heap.
Is it allowed to be collected, according to provided image?
2) What "Native Stack" mean?
As far as I understood, it's accounted as GC root.
http://help.eclipse.org/mars/index.jsp?topic=%2Forg.eclipse.mat.ui.help%2Fconcepts%2Fgcroots.html
Why some object (i.e. Order 0x782032cf8) is kept in "Native Stack"?
3) If I have reference from GC Root to object A, that object will not be garbage collected? Right?
And if so, my Order_Item object can't be garbage collected?
4) If 3 is right, how may I find what keeps objects 0x7821da5e0 and 0x782032cf8, and how to dereference/remove them?
You cannot really force the garbage collector to delete a given object. You know that the object is kept alive as long as it is reachable by references from the given point in the program. But if the object gets "collectable", it might be collected soon, but if there is no pressure on memory, it may fool around for a long time.
Usually, there is not reason to really delete objects if there is enough memory. The only exception I know are passwords. Here, you use a char array and overwrite it with nonsense once you used it.
For the native stack: Your link indicates that the native stack keeps external resources, e.g. files.

Is an object garbage if it is referenced only from garbage?

Suppose there is an object a of class A, which holds a reference to another object b of class B. And this is the only reference to b. So now, if all references to a is removed, then a is ready to GC. Does this mean that b is also ready to get garbage collected? because, though b has a reference ( inside a ), it is unreachable, because a is unreachable.
So how exactly does this scenario works? I mean the order of garbage collection.
Once an object is unreachable from a root, it will be collected. See this question for an explanation of GC roots.
Entire subgraphs will be collected (as you describe) presuming no node within that subgraph may be reached.
Java (and .NET) use mark and sweep garbage collection which deals with this kind of problem.
Reference count-based systems (such as C++'s std::shared_ptr<T>) may fail in the case of circular dependencies that remain unreachable. This is not a problem for Java/.NET GC.
Java GC is smart enough to collect islands of isolated objects though they maybe pointing to each other. Hence, b also becomes eligible for garbage collection. The point to note here is that although you have a reference to b it's not live in the sense that it cannot be reached from your program's root.
It depends on the GC. A JVM can be told to use different GC's and typically uses 3 GC's as one (eden, copy, markcompact).
In any typical GC and in refcounting the situation you described is handled cleanly, both objs are collected. Think of it in 2 stages: first "a" gets noticed and collected then "b" gets noticed and collected. Again: the specific means of noticing depends on the GC.
Even if the objects reference internally to each other, and they do not have a reachable reference from program, they will be eligible for GC. THere is a good explanation with diagrams here
http://www.thejavageek.com/2013/06/22/how-do-objects-become-eligible-for-garbage-collection/
That is exactly the point of GC. Since b is unreachable from main thread, it will be garbage collected. It is not just the count that matters.

Preventing java garbage collection by making cyclic linked lists? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Garbage Collection in Java and Circular References
Java runs it's garbage collector whenever there is not enough space in the memory . It does so by deleting the unreferenced objects. So what if an object has a pointer that points to itself ,or any cyclic pointing structure that always has a pointer to it ? Will the garbage collector fail or will it recognize any such insidious attempts made by us in order to make it fail ?
Whether the objects will be collected depends on the Garbage collecting algorithm
reference-counting GC, will not collect cyclic references
but, modern GC algorithms usually decide eligibility of an object for collection by traversing the heap starting from the root set.
Garbage collector will collect objects that are not accessible from the root set of references (current local variables, static references, operand stacks of stack frames). This means that even objects that are referenced by some other objects can still be collected.
Therefore, your cyclic-pointer structure will get collected even though each object is referenced iff there is no other reference path going transitively from the root set to the objects forming the cycle.
See also What triggers the Java Garbage Collector.
The Java garbage collector will not reclaim any memory of objects that are pointed to by static or local variables, or by any objects linked (recursively) from those objects. Thus if you have large linked trees of objects, the garbage collector will not reclaim that space if there is a variable pointing to any root of a tree or loop.
The memory for objects linked in a loop will be reclaimed as long as there is no static or local variable pointing to an object in the loop. Thus if you want garbage collection to work efficiently, be sure to null out variables when the objects are no longer needed.
The garbage collector does detect, and does not care, if objects are linked in cyclic ways. The only thing that matters with whether the object can be reached from a variable.
"A references object B and B references A" is called an island of isolation. GC is smart enough to detect such things. If there is no reference to any object in an island the whole island is eligible for garbage collection

Garbage Collection in Java

On the slides I am revising from it says the following:
Live objects can be identified either by maintaining a count of the number of references to each object, or by tracing chains of references from the roots.
Reference counting is expensive – it needs action every time a reference changes and it doesn’t spot cyclical structures, but it can reclaim space incrementally.
Tracing involves identifying live objects only when you need to reclaim space – moving the cost from general access to the time at which the GC runs, typically only when you are out of memory.
I understand the principles of why reference counting is expensive but do not understand what
"doesn’t spot cyclical structures, but it can reclaim space incrementally." means. Could anyone help me out a little bit please?
Thanks
Reference counting doesn’t spot cyclical structures...
Let's say you have two objects O1 and O2. They reference each other: O1 -> O2 and O2 -> O1, and no other objects references them. They will both have reference count 1 (one referrer).
If neither O1 or O2 is reachable from a GC root, they can be safely garbage collected. This is not detected by counting references though, since they both have reference count > 0.
0 references is a sufficient but not necessary requirement for an object to be eligible for garbage collection.
...but it can reclaim space incrementally.
The incremental part refers to the fact that you can garbage collect some of the 0-referenced objects quickly, get interrupted and continue at another time without problems.
If a tracing-algorithm gets interrupted it will need to start over from scratch the next time it's scheduled. (The tree of references may have changed since it started!)
Simple reference counting cannot resolve cases, when A refers to B and B refers to A. In this case, both A and B will have reference count 1 and will not be collected even if there are no other references.
Reference counting can reclaim space immediately when some object's reference counter becomes 0. There is no need to wait for GC cycle, scan other objects, etc. So, in a sense, it works incrementally as it reclaims space from objects one by one.
"doesn't spot cyclical structures"
Let's say I've got an object A. A needs another object called B to do its work. But B needs another object called C to do its work. But C needs a pointer to A for some reason or other. So the dependency graph looks like:
A -> B -> C -> A
The reference count for an object should be the number of arrows pointing at it. In this example, every object has a reference count of one.
Let's say our main program created a structure like this during its execution, and the main program had a pointer to A, making A's count equal to two. What happens when this structure falls out of scope? A's reference count is decremented to one.
But notice! Now A, B, and C all have reference counts of one even though they're not reachable from the main program. So this is a memory leak. Wikipedia has details on how to solve this problem.
"it can reclaim space incrementally"
Most garbage collectors have a collection period during which they pause execution and free up objects no longer in use. In a mark-and-sweep system, this is the sweep step. The downside is that during the periods between sweeps, memory keeps growing and growing. An object may stop being used almost immediately after its creation, but it will never be reclaimed until the next sweep.
In a reference-counting system, objects are freed as soon as their reference count hits zero. There is no big pause or any big sweep step, and objects no longer in use do not just sit around waiting for collection, they are freed immediately. Hence the collection is incremental in that it incrementally collects any object no longer in use rather than bulk collecting all the objects that have fallen out of use since the last collection.
Of course, this incrementalism may come with its own pitfalls, namely that it might be less expensive to do a bulk GC rather than a lot of little ones, but that is determined by the exact implementation.
Imagine you have three objects (A, B, C): A has a reference on B, B has a reference on C and C has a reference on A. But no other object has any reference on one of these. It's an independent cyclical structure. Using traditional reference counting would prevent the garbage collector from remove the cycle because every object is still referenced. But as long as no one has a reference on one of the three they could/should be removed. I guess reclaiming space incrementally means the way reference counting works when finding unreferenced instances, no cycles etc.
An object can be released for garbage collecting if the reference count reaches 0.
For circular reference this will never happen as each object in the circle keeps a reference to another so they are all at least 1.
For that some graph theory is needed to detect references which are no longer attached to anything, like little islands in the Heap sea. In order to keep these in memory they must have some 'attachment' to a static variable somewhere.
That is what tracing does. It determines which parts of the heap are islands and can be freed and which are still attached to the mainland i.e. static variables smewhere.

Categories