Frage

Given:

class Finalizer {
    static int x = 0;
    static boolean gc = false;
    public static void main(String[] args) {
        for(x=0; x<100000; x++) {
            new Finalizer().finalize();
        }
        x = 0;
        gc = true;
        System.gc();
    }
    protected void finalize() {
        if(gc == true) x++;
        if(x % 10000 == 0)
           System.out.println(gc + " " + x);
    }
}

Which are always true? (Choose all that apply.)

A: true will never be an output
B: true will be output at least ones
C: If true and false are both output, their respective values for x can be the same.
D: If true and false are both output, their respective values for x can never be the same.

The solution says C is correct, and I do not understand why, can someone please explain what is happening here.

War es hilfreich?

Lösung

What's going on is this: finalize() overrides a method in the Object class. The javadoc explains when this is called. When an object is no longer referenced anywhere, it may then be garbage-collected; but when it's garbage-collected isn't defined by the language.

The finalize() method will be called on each Finalize object when it's garbage-collected. Of course, the code you posted also calls finalize() explicitly.

In this example, the loop will call new Finalize() 100,000 times to create new Finalize objects. Each time a new object is created, it's used to call finalize() explicitly, but then it's no longer used, so it could be garbage-collected right away. The consequence of this is that by the time we get to the System.gc() call, we don't know how many Finalize objects are still around waiting to be garbage-collected, but it could be anywhere from 0 to 100,000. (On my machine, it seems to be 1. That is, it's already garbage-collected all but one of the objects, and called finalize() on them.)

During the first loop, x will go from 0 to 999,999 (the finalize() method won't modify x), and therefore you should see false x for every x that is a multiple of 10,000. (Note that finalize() could also be called by the runtime for objects that are garbage-collected early, so in theory it's possible to see false x for the same x more than once.)

After the first loop, if N is the number of objects still to be garbage-collected, then System.gc() should cause them all to be garbage-collected at that point (it's not guaranteed); since x has been reset to 0 and finalize() will increment it, that means x will go from 1 to N. (Note that the first finalize() will increment x from 0 to 1 before the x % 10000 test.) You should see true x for every x in the range 1 to N that is a multiple of 10,000.

But since N could be anything from 0 to 100,000, that means that we may or may not see any true outputs--we can't tell. That's why neither A nor B is "always true". If we do see any true outputs, since the output will show every multiple of 10,000 in its range, it's certain that the true output will have the same number as a previous false output, which explains why C is correct and D is not.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top