3

I was going through the Java Garbage Collection process and different scenarios in which GC is applicable.

Below is the scenario I am confused about :

List<X> listX = new ArrayList<X>();

    for(int a = 0;a<100;a++){
        listX.add(new X(a));


    }

    for (X xObject : listX) {
        xObject.printValue();
    }

In the first loop I am adding the new objects in each loop and in the latest loop I am just printing the values, so, are those objects which I am adding in the list applicable for GC?

What does this sentence mean ?

"One more excellent example for when an instance can become eligible for garbage collection. All the properties of an instance can be stored in the register and thereafter the registers will be accessed to read the values. There is no case in future that the values will be written back to the instance. Though the values can be used in future, still this instance can be marked eligible for garbage collection"

Kedar Parikh
  • 807
  • 1
  • 14
  • 19
  • It highly depends on the given scope of the variable and the scope of the surrounding list I would say. The entries of your list are still referenced by your list, so that by themself they aren't applicable for gc. – Aron_dc Oct 21 '15 at 11:46

5 Answers5

9

No, they're not, since they're referenced by the array which is referenced by the ArrayList whose reference is in the stack of the current thread:

thread stack --> ArrayList --> array --> x1, x2, x3, etc.
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
3

The lifetime of the objects you add to the list is related to the lifetime of the list itself, because from what I see from the code, listX is the only object holding references to X objects. So, X objects will be collected when listX is not referenced any longer. Check @JBNizet to see how they are actually referenced or connected (+1). Always think like this, how my objects are connected and if they still referenced all the way back to GC Roots, and remember Java is smart, it doesn't do reference counting :)

Community
  • 1
  • 1
Sleiman Jneidi
  • 22,907
  • 14
  • 56
  • 77
1

If you consider the following code, changed it up a bit.

List<X> listX = new ArrayList<X>();

    for(int a = 0;a<100;a++){
        X tmpX = new X(a);
        X unusedX = new X(a);

        listX.add(tmpX);
}

When the new keyword is called, a new object is created on the Heap. This means in this example, it will create a tmpX and a unusedX. You are adding the tmpX to the array, therefor meaning it has a reference in the ListX. When it's garbage collection time, the garbage collector will check for objects there only live in the current iteration of the for scope, defined by the {} brackets. unusedX will be collected, but since tmpX will have a reference in the list, it is kept on the heap.

mrhn
  • 17,961
  • 4
  • 27
  • 46
0

Garbage collection only frees memory held by objects that are no longer strongly reachable from any root, for instance in the case of circular dependencies. The references to each of the new X objects are held in the List and so they won't get garbage collected.

Andi Emma Davies
  • 298
  • 4
  • 19
  • That's incorrect. Objects that are still referenced can be GCed if they're not strongly reachable from any root anymore. That what allows circular dependencies to be GCed: A -> B and B -> A. – JB Nizet Oct 21 '15 at 11:49
  • Well, sounds like I don't know as much about garbage collection as I thought I did... Could you elaborate as to why it's wrong/which parts are wrong, @SleimanJneidi? – Andi Emma Davies Oct 21 '15 at 21:02
0

No, if this piece of code is reachable, if not it will be illegible. The garbage collector will look for objects which aren't being used any more, gets rid of them and free up the memory.

Weslor
  • 22,180
  • 2
  • 20
  • 31