Reputation: 16843
When I create a native implementation peer in c++ how can I ensure that native part is also deleted when java object is deleted by JVM? I can add some methods that user of java object has to call explicitly, but I'd like to know if there some hook that I could put to handle when java object is deleted (garbage collected) so that I can automatically delete c++ implementation object as well.
I reviewed JACE it seems that it does that, but I'd need to run PeerEnhancer to patch generated class file (probably that's how it hooks delete? or maybe it needs this patching for something else). However, I'd like to avoid messing with compiled java files, I don't want anything fancy
Upvotes: 3
Views: 1668
Reputation: 7278
Please be aware that by embracing finalizers, you are tickling JVM in the worst possible place. Invoking JNI in finalizer() is like adjusting engine valve timing while driving. While it is technically possible, it is also very easy to end up with leaking JVM or a crash. With even slightest touch of multithreading, you will deadlock/crash at some point for sure. If you say "i don't want anything fancy", i would suggest going with explicitly called methods. Yes requiring certain method order by convention is dirty design, but then JNI is dirty in general.
If a respected JNI library does an undercover class instrumentation instead of simply using finalizers, it perhaps has a reason. Some recommended reading (and that does not even mention JNI!):
http://asserttrue.blogspot.com/2008/11/finalization-is-evil.html
http://elliottback.com/wp/java-memory-leaks-w-finalize-examples/
My suggestion is: yes implement a baseclass with a virtual method detachFromPeer(), set some "detached" flag in it and then in finalizer just check the flag with some warning.
Upvotes: 4
Reputation: 310860
This is a rare case where you should really use a finalizer, but you should also make your Java class Closeable as well.
Upvotes: 2