When we add a call to System.gc() to the example from
the bug item #422966, ORP crashes with an invalid
memory access. The same example works with a smaller
number of objects to finalize (e.g., numObj=1000), but
it crashes for numObj=550000. Here's the example code:
public class testFinalize {
static int next_id=0;
static int numObj=550000; // ORP crashes
//static int numObj=1000; // ORP works fine
int id;
public testFinalize() {
id = next_id++;
}
public static void main(String[] str){
testFinalize[] fo = new testFinalize
[testFinalize.numObj];
for(int i=0; i<testFinalize.numObj; i++){
fo[i] = new testFinalize();
if( i%(testFinalize.numObj/10) == 0 ){
fo[i] = new testFinalize();
System.out.println
("main thread running...");
}
}
System.gc();
}
protected void finalize(){
System.out.println("Finalizing object " + id);
}
}
Logged In: YES
user_id=202559
see bug ID 422453
Logged In: YES
user_id=202559
We need still open the bug, because I found finalizer runs
differently in O3 and O1. In O3, it finalizes all the
objects that have finalize() defined. This may easily incur
another bug that: because finalizer is called by GC when GC
finishes, running lots of finalizers may trigger another
cycle of GC(e.g. the finalizer printing a string need new a
String object), then behaviour may be undefined. Anyway, it
happens rarely, but if O3 finalizes all the objects which
have finalize() defined, it may be not so rare.
Logged In: YES
user_id=202559
It turns out that this bug is not happily to be fixed,
because it's a related to JIT in a subtle way. That is, in
the following code,
Object objref = new ObjectFinalizable(); //Object 1
System.gc();
objref = new ObjectFinalizable(); //Object 2
JIT can easily find out the first created object is lost
since objref will be assigned another object. So the
reference to object 1, say, objref_1, would be considered
not live when GC happens, i.e. objref_1 has status changed
from "Reachable, Unfinalized" to "F-Reachable,
Unfinalized". Then GC will finalize it.
But it's not compliant with the spec, since objref_1 is of
course live from GC's point of view when GC happens. It
should not be finalized.
The problem becomes how to keep GC happy while JIT still
optimizes.