/** *Testaclasswithabadfinalizer. * *Thistestisinherentlyflaky.Itassumesthatthesystemwillschedulethefinalizerdaemon *andfinalizerwatchdogdaemonenoughtoreachthetimeoutandthrowingthefatalexception. *Thisusessomewhatsimplerlogicthan2041-bad-cleaner,sincethehandshakeimplementedthere *ishardertoreplicatehere.Webumpupthetimeoutbelowabittocompensate.
*/ publicclass Main { publicstaticvoid main(String[] args) throws Exception {
System.loadLibrary(args[0]);
ClassLoader cl = Main.class.getClassLoader();
NativeAllocationRegistry registry =
NativeAllocationRegistry.createNonmalloced(cl, getBadFreeFunction(), 666); // Replace the global uncaught exception handler, so the exception shows up on stdout. Thread.setDefaultUncaughtExceptionHandler(newThread.UncaughtExceptionHandler() { publicvoid uncaughtException(Threadthread, Throwable e) { if (e instanceof TimeoutException) {
System.out.println("TimeoutException on "
+ thread.getName() + ":" + e.getMessage());
} else {
System.out.println("Unexpected exception " + e);
}
System.exit(2);
}
}); // A separate method to ensure no dex register keeps the object alive.
createBadCleanable(registry);
// 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 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. // The RQ timeout is currently effectively 5 * the finalizer timeout. // 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 = 150 * 1000 + 5 * 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 createBadCleanable(NativeAllocationRegistry registry) {
Object badCleanable = new Object(); long nativeObj = getNativeObj();
registry.registerNativeAllocation(badCleanable, nativeObj);
System.out.println("About to null reference.");
badCleanable = 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.