I have an SDK/NDK based app that creates native buffers and then reads/writes data to there to communicate through JNI bridge. in 4.4 (DALVIK) it functions OK - or at least it was not throwing an exception. Once ART became mandatory, i.e. Lollipop - it now fails on app close/exit. Creating the direct buffer here:
JNIEXPORT void JNICALL Java_com_class_nativeOnDirect(JNIEnv* jenv, jobject obj, jobject m, jobject mv){
GLubyte* _dData;
_dData = (GLubyte*)jenv->GetDirectBufferAddress(m);
}
Clearing the direct data:
JNIEXPORT void JNICALL Java_com_class_nativeOnFreeNativeBuffer(JNIEnv* jenv, jobject obj, jobject m){
jenv->DeleteGlobalRef(m);
}
After some research into this - still not exactly clear to me as to why this happens. BTW - if the "DeleteGlobalref(jobjct) does not happen - the exception is not thrown. Afraid of a memory leak here. Thanks in advance
You shouldn't call
DeleteGlobalRef
on a local ref - only on the actualjobject
pointers that you've got returned fromNewGlobalRef
. So in this case, as long as you aren't callingNewGlobalRef
, you don't need to callDeleteGlobalRef
either.You only need to use
NewGlobalRef
if you store a reference to an object on the native side, for use after the JNI function call returns.ART is a little bit stricter than dalvik when it comes to using the JNI API correctly, so the code has been incorrect all along, it just hasn't triggered any errors. See http://android-developers.blogspot.fi/2011/07/debugging-android-jni-with-checkjni.html for tips on how to enable CheckJNI for stricter checking, to be able to catch issues like these earlier.