jni内存释放

调用GetStringUTFChars,GetDoubleArrayElements等相关方法时,用完之后需要对应调用ReleaseStringUTFChars,ReleaseDoubleArrayElements

调用GetObjectArrayElement不需要释放,但用完需要调用DeleteLocalRef删除对应局部引用


jstring tempObj = (jstring)env->GetObjectArrayElement(array, j);
env->DeleteLocalRef(tempObj);

jobjectArray args =(env)->NewObjectArray(nCount,(env)->FindClass("java/lang/String"),0);

args 一般作为返回值使用,此时不需要删除引用。如果只是在jni层使用,不作为返回值,则需要删除。 NewStringUTF与NewObjectArray情况类似。

JNI 中的 Local Reference 只在 native method 执行时存在,当 native method 执行完后自动失效。这种自动失效,使得对 Local Reference 的使用相对简单,native method 执行完后,它们所引用的 Java 对象的 reference count 会相应减 1。不会造成 Java Heap 中 Java 对象的内存泄漏。
而 Global Reference 对 Java 对象的引用一直有效,因此它们引用的 Java 对象会一直存在 Java Heap 中。程序员在使用 Global Reference 时,需要仔细维护对 Global Reference 的使用。如果一定要使用 Global Reference,务必确保在不用的时候删除。就像在 C 语言中,调用 malloc() 动态分配一块内存之后,调用 free() 释放一样。否则,Global Reference 引用的 Java 对象将永远停留在 Java Heap 中,造成 Java Heap 的内存泄漏。

1)     释放String
jstring jstr = NULL;
char* cstr = NULL;
//调用方法
jstr = (*jniEnv)->CallObjectMethod(jniEnv,mPerson, getName);
cstr = (char*)(*jniEnv)->GetStringUTFChars(jniEnv,jstr, 0);
__android_log_print(ANDROID_LOG_INFO,"JNIMsg", "getName  ---->  %s",cstr );
//释放资源
(*jniEnv)->ReleaseStringUTFChars(jniEnv,jstr, cstr);
(*jniEnv)->DeleteLocalRef(jniEnv,jstr);


2)     释放 类 、对象、方法
(*jniEnv)->DeleteLocalRef(jniEnv, XXX);

“XXX” 代表 引用对象

3)     释放 数组家族
jobjectArrayarrays = NULL;
jclass jclsStr =NULL;
jclsStr =(*jniEnv)->FindClass(jniEnv, "java/lang/String");
arrays =(*jniEnv)->NewObjectArray(jniEnv, len, jclsStr, 0);
(*jniEnv)->DeleteLocalRef(jniEnv,jclsStr);  //释放String类
(*jniEnv)->DeleteLocalRef(jniEnv,arrays); //释放jobjectArray数组

native method 调用 DeleteLocalRef() 释放某个 JNI Local Reference 时,首先通过指针 p 定位相应的 Local Reference 在 Local Ref 表中的位置,然后从 Local Ref 表中删除该 Local Reference,也就取消了对相应 Java 对象的引用(Ref count 减 1)

DeleteGlobalRef() 删除 Global reference 和它引用的 Java 对象。Global reference 管理不当会导致 Java Heap 的内存泄漏

猜你喜欢

转载自iaiai.iteye.com/blog/2245785