java garbage collection and null reference

2019-01-27 04:49发布

问题:

In my studying for OCJP I came across the following question:

class CardBoard {
           Short story = 200;
           CardBoard go(CardBoard cb) {
                cb = null;
                return cb;
           }
           public static void main(String[] args) {
             CardBoard c1 = new CardBoard();
             CardBoard c2 = new CardBoard();
             CardBoard c3 = c1.go(c2);
             c1 = null;
            // do Stuff 
}}

When //doStuff is reached, how many objects are eligible for GC?
The correct answer is 2, meaning c1 and its story object.

When line //doStuff is reached, c3 is also null. Why isn't it eligible for GC too?

回答1:

c3 is a local handle with a null reference, it does not point (and hever has pointed) to an allocated object. Therefore there's nothing to GC.



回答2:

c3 is not an object. It's a variable referencing null. A variable can't be eligible to GC. Only objects can be eligible to GC.

The objects eligible to GC are the Cardboard which was initially referenced by c1, and the Short instance initially referenced by the CardBoard initially referenced by c1.



回答3:

Garbage collector scans for objects in memory and when it finds one checks for handles pointing at it (and not vice verse) When Garbage Collector is called the objects (inside memory) that have no handle pointing to them are removed from memory. In this occasion of code you only have 2 objects created in memory but three handles. Garbage Collector will only delete at max 2 objects (since only two objects exist) C3 was only pointing at a null position. C1,C2,C3 are not removed. The objects that they used to point are removed (in case no other handle points at them). So at this point since C3 never pointed to an object in memory setting it to null does not make a difference for the Garbage Collector.

Hope I was helpful



回答4:

Your CardBoard#go() method does nothing. It receives reference to some object, immediately forgets it, replacing by null, and returns this null value.

So, the line

CardBoard c3 = c1.go(c2);

also does nothing, i.e. no object is created. Just null assigned to c3. So it is not garbage collected because it is already not exist.



回答5:

The c3 itself is just a reference variable, which is not in the heap space (i.e. not in the scope of garbage collection)

The line CardBoard c3 = c1.go(c2); only sets the c3 reference to null Thus c3 has not impact on garbage collection as it doesn't make any object eligible.



回答6:

c3 has no references to an object,it is just to make some confusion.

We have created two objects c1 and c2, what we are missing out is wrapper objects of type Short, so basically we have created four objects in total.

When we are making c1 = null it means that short object which we are accessing using c1 is available for GC, not the short object which we can access using c2.

This can be verified using following code:

public class CardBoard {

Short story = 200;

CardBoard go(CardBoard cb) {
    cb = null;
    return cb;
}

public static void main(String[] args) {
    Runtime run = Runtime.getRuntime();

    CardBoard c1 = new CardBoard();
    CardBoard c2 = new CardBoard();
    CardBoard c3 = c1.go(c2);

    // System.out.println(run.freeMemory());

    run.gc();
    // System.out.println(run.freeMemory());

    c1.story = 100;

    System.out.println(c1.story);
    c1 = null;
    run.gc();

    System.out.println(c2.story);

}

}

output: 100 200

which means that c1 and Short story which we can access from c1 is available for garbage collection not Short story of c2.