// A separate method to ensure no dex register keeps the object alive.
createBadFinalizer(finalizerWait);
// Should have at least two iterations to trigger finalization, but just to make sure run // some more. for (int i = 0; i < 5; i++) {
Runtime.getRuntime().gc();
}
// Now wait for the finalizer to start running. Give it a minute.
finalizerWait.await(1, MINUTES);
// Now fall asleep with a timeout. The timeout is large enough that we expect the // finalizer daemon to have killed the process before the deadline elapses. // The timeout is also large enough to cover the extra 5 seconds we wait // to dump threads, plus potentially substantial gcstress overhead. // Note: the timeout is here (instead of an infinite sleep) to protect the test // environment (e.g., in case this is run without a timeout wrapper). finallong timeout = 100 * 1000 + VMRuntime.getRuntime().getFinalizerTimeoutMs(); long remainingWait = timeout; finallong waitStart = System.currentTimeMillis(); while (remainingWait > 0) { synchronized (args) { // Just use an already existing object for simplicity... try {
args.wait(remainingWait);
} catch (Exception e) {
System.out.println("UNEXPECTED EXCEPTION");
}
}
remainingWait = timeout - (System.currentTimeMillis() - waitStart);
}
// We should not get here.
System.out.println("UNREACHABLE");
System.exit(0);
}
privatestaticvoid createBadFinalizer(CountDownLatch finalizerWait) {
BadFinalizer bf = new BadFinalizer(finalizerWait);
System.out.println("About to null reference.");
bf = null; // Not that this would make a difference, could be eliminated earlier.
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.