3

I know System.gc() is not guaranteed to cause GC, but theoretically, in the following code, will the object obj be eligible for garbage collection?

public class Demo {

    public static void main(String[] args) throws Exception {
        SomeClass obj = new SomeClass();
        ArrayList list = new ArrayList();
        list.add(obj);
        obj = null;
        System.gc();
    }

}

class SomeClass {
    protected void finalize() {
        System.out.println("Called");
    }
}
Manish
  • 3,913
  • 2
  • 29
  • 45
  • 3
    There's also no guarantee that `finalize` will ever be called – MadProgrammer Mar 19 '13 at 06:15
  • Not eligible because your obj reference is null but in list that exists which is still reachable. – Nandkumar Tekale Mar 19 '13 at 06:17
  • 1
    While the answers is "no" (assuming that variables are always strong roots), this is an interesting point. In .NET/C#, the SomeClass object *might* be garbage collected, as `list` is itself not used [later]. This is an actual .NET issue with timer callbacks within a long-running method. The question is: *in Java*, is *every* variable on the visible stack *always* guaranteed to be a strong root? –  Mar 19 '13 at 06:52

5 Answers5

8

At the point where you call System.gc() the SomeClass instance you created is not eligible for garbage collection because it is still referred to by the list object, i.e. it is still reachable.

However, as soon as this method returns list goes out of scope, so obj will then become eligible for garbage collection (as will list).

Simply setting the reference obj to null does not, by itself, make the object referred to eligible for garbage collection. An object is only eligible if there are no references to it from the graph of visible objects.

Cameron Skinner
  • 51,692
  • 2
  • 65
  • 86
  • When you set obj to null, wouldn't it become null in the list as well? List is just pointing to the same location where obj was earlier. – Sudhanshu Umalkar Mar 19 '13 at 06:19
  • 5
    No. Java uses references, not pointers. When you add an item to a list, it takes a copy of the reference and stores that. Changing the original reference does not change the copied reference, so the `SomeClass` instance is still reachable. – Cameron Skinner Mar 19 '13 at 06:20
  • Agreed, it won't be garbage collected in the above case. – Sudhanshu Umalkar Mar 19 '13 at 06:25
4

will the object obj be eligible for garbage collection?

Only those objects are garbage collected who don't have even one reference to reach them. (except the cyclic connectivity)

In you code, there are two reference that are pointing to new SomeClass();

  1. obj
  2. zeroth index of list

You put obj = null, i.e. it's not pointing to that object anymore. But, still there exists another reference in list which can be used to access that object.

Hence the object will be eligible for GC only when main returns. i.e. you can't see the output of finalize method even if it got called. (not sure if JVM still calls it)

Azodious
  • 13,752
  • 1
  • 36
  • 71
  • Where is the guarantee that `list` is a strong root? (I'm sure it's in some specification :-) The `list` object is not used *after* the call to `System.gc`, so technically, it isn't "needed" after and could thus (this is where I am not sure of the guarantees) may be elligible for garbage collection itself? Or does the very presence of the callframe *require* that all local variables are strong roots under all conditions? Even when JIT'ed? –  Mar 19 '13 at 07:02
3

No, because the object actually exists in the list.

Ankit
  • 6,554
  • 6
  • 49
  • 71
1

You as Java programmer can not force Garbage collection in Java; it will only trigger if JVM thinks it needs a garbage collection based on Java heap size

When a Java program started Java Virtual Machine gets some memory from Operating System. Java Virtual Machine or JVM uses this memory for all its need and part of this memory is call java heap memory.

Heap in Java generally located at bottom of address space and move upwards. whenever we create object using new operator or by any another means object is allocated memory from Heap and When object dies or garbage collected ,memory goes back to Heap space in Java

EDIT :

will the object obj be eligible for garbage collection?

No, because the object is still in the ArrayList.

Ajay S
  • 48,003
  • 27
  • 91
  • 111
  • 1
    The question was about whether the object is *eligible* for garbage collection. – Cameron Skinner Mar 19 '13 at 06:19
  • 1
    Yes he is. He also pointed out that he knows that it doesn't *force* a garbage collection run. You haven't answered the question: "will the object `obj` be eligible for garbage collection?" – Cameron Skinner Mar 19 '13 at 06:22
-2

Agreed, it won't be garbage collected as long as its there in the list.

Sudhanshu Umalkar
  • 4,174
  • 1
  • 23
  • 33