JNI object lifetimes - quick referenceFeb 1, 2016
I’ve recently had reason to do a bit of work with JNI . Throughout the course of this work I had to do quite a lot of Googling in order to figure out how to properly manage the caching of various JNI objects used by my C++ code. Some JNI objects can be safely cached and re-used at any point, while others have limited lifetimes and require special handling. Obtaining JNI objects through JNI APIs is, broadly speaking, fairly expensive, so it’s smart to persist those objects which will be re-used in multiple places. You just need to be careful.
I expected to find a big table somewhere that documented the lifetime restrictions (or lack thereof) for each of the JNI object types, but sadly I was unable to locate one. Instead, I wound up trawling through numerous Stack Overflow replies, blogs, forums, and other documentation to obtain this information.
This post is my effort to provide to others the missing quick reference I wish I’d found. I recommend this Android documentation as further reading if you want more details.
|JNI Object||Use across JNI calls?||Use on different thread?||Notes|
||Yes||Yes||To obtain an instance of
Otherwise, you don't need to clean up a
|Primitive value types
||Yes||Yes||These are just aliases for normal native value types, so there are no special lifetime or cleanup considerations.|
||No (local refs)||No (local refs)||
If one of these is passed in as an argument to a JNI call, or returned from another JNI API, it is typically a local reference
and is only valid for the duration of that JNI call, on that same thread. These do not require any cleanup.
A durable global reference can be created from any local reference by calling
|Yes (global refs)||Yes (global refs)|
||Yes||Yes||These are durable and can be used without restriction. No cleanup is required.|