Solution to b4a5: Observing the garbage collector
See code at solutions/code/tutorialquestions/questionb4a5
The package-visible static field in class A
should be declared as follows:
static int numCollected = 0;
---remember that default visibility is package visibility.
The finalize
method in my solution looks like this:
@Override
public void finalize() {
System.out.println("Instance " + id + " collected");
numCollected++;
}
Note that I have marked this method with @Override
because finalize
is provided by the Object
class. Note also that incrementing numCollected
increments the static field numCollected
, thus this change is visible to all objects of type A
: because the field is declared static, its value is
shared across the class.
My main
method looks like this:
public static void main(String[] args) {
for(int i = 0; i < 1000000; i++) {
new A(i);
}
System.out.println("Number of instances of A garbage-collected: " + A.numCollected);
}
I ran this three times on my desktop, and here is an abbreviated version of the last few lines of output generated by each run:
Run 1:
Instance 263256 collected
Instance 263255 collected
Instance 263254 collected
Number of instances of A garbage-collected: 28347
Instance 263253 collected
Instance 263252 collected
...
Instance 263228 collected
Instance 263227 collected
Instance 263226 collected
Run 2:
Instance 495435 collected
Instance 495434 collected
Instance 495433 collected
Number of instances of A garbage-collected: 33842
Instance 495432 collected
Instance 495430 collected
...
Instance 495415 collected
Instance 495414 collected
Instance 495413 collected
Run 3:
Instance 523514 collected
Instance 802356 collected
Instance 523515 collected
Number of instances of A garbage-collected: 25859
Instance 802352 collected
Instance 523519 collected
Instance 802334 collected
Instance 523537 collected
Instance 802333 collected
From this, we learn the following:
-
The garbage collector does not necessarily collect all garbage produced by the program before the program terminates. In this program, I created 1000000 garbage objects of type A, but in each run fewer than 40000 of them were garbage collected. (Of course, when your program terminates, all the memory it used becomes is reclaimed by the operating system, so this is not a problem.)
-
Different numbers of objects are garbage-collected during different runs of the program
-
There is no guarantee about the order in which objects will be garbage-collected: this varies run-to-run
-
As a result of this, there is no guarantee as to when, if at all,
finalize
will be invoked for an object that becomes garbage