That gets called when the class loader is garbage collected.
The default class loader is never garbage collected, so unless you are using your own class loader that method will never be called.
And it is possible that even your own class loaders will never be garbage collected, particularily on application exit. So it might not be called then.
Would it be considered a JNI bug if I had a global variable in my C++ DLL code that was deallocated correctly when calling System.runFinalizersOnExit(true), but if I don't call it, the Java VM overwrites the global variable with garbage causing a crash when my DLL tries to unload itself?
Even more accurately, each class loader keeps loaded native library using objects of the class ClassLoader.NativeLibrary (not a public class, a packege private static class inside ClassLoader). The unload is called in the finalize() of ClassLoader.NativeLibrary. So only when those NativeLibrary objects' finalize() are called. Since you cannot get access to those private objects inside ClassLoader, so the only sure way to get unload() called is using System.runFinalizerOnExit(true);
so that the JVM is forced to call finalize() on EVERY object if it's not called earlier.
I see... It makes sense. But since runFinalizersOnExit() is a deprecated method, isn't it bad practice to use it? I would love to find the "Correct" way to fix my problem so my global memory will stop getting trashed.
By the way, thanks for the great answers so far. It is all starting to make more sense to me :)
If you just want to do some cleanup in your native lib, you can expose this native unload cleanup method as another Java native method and use Runtime.addShutdownHook() to call it before the program terminates.
You can also use System.runFinalization() in that shutdown hook if you want.
>...System.runFinalizersOnExit(true)...
There is absolutely no way to guarantee that java will call finalize(). Do not rely on it for clean up.
> ...native method and use Runtime.addShutdownHook()
The best and only guaranteed way to do this is to explicitly call your own clean up method. You can use addShutdownHook to do this.