在c++中new的对象,如果不返回java,必须用release掉,否则内存泄露。包括NewStringUTF,NewObject。如果返回java不必release,java会自己回收。
jstring jstr = env->NewStringUTF((*p).sess_id);
...
env->DeleteLocalRef( jstr);
jobject jobj = env->NewObject(clazz,midInit);
return jobj;
总体原则:释放所有对object的引用
1.FindClass
jclass ref= (env)->FindClass("java/lang/String");
env->DeleteLocalRef(ref);
2.NewString / NewStringUTF / NewObject / NewByteArray
jstring (*NewString)(JNIEnv*, const jchar*, jsize);
const jchar* (*GetStringChars)(JNIEnv*, jstring, jboolean*);
void (*ReleaseStringChars)(JNIEnv*, jstring, const jchar*);
jstring (*NewStringUTF)(JNIEnv*, const char*);
const char* (*GetStringUTFChars)(JNIEnv*, jstring, jboolean*);
void (*ReleaseStringUTFChars)(JNIEnv*, jstring, const char*);
env->DeleteLocalRef(ref);
3.GetObjectField/GetObjectClass/GetObjectArrayElement
jclass ref = env->GetObjectClass(robj);
env->DeleteLocalRef(ref);
4.GetByteArrayElements和GetStringUTFChars
jbyte* array= (*env)->GetByteArrayElements(env,jarray,&isCopy);
(*env)->ReleaseByteArrayElements(env,jarray,array,0);
const char* input =(*env)->GetStringUTFChars(env,jinput, &isCopy);
(*env)->ReleaseStringUTFChars(env,jinput,input);
5.NewGlobalRef/DeleteGlobalRef
jobject (*NewGlobalRef)(JNIEnv*, jobject);
void (*DeleteGlobalRef)(JNIEnv*, jobject);
例如,
jobject ref= env->NewGlobalRef(customObj);
env->DeleteGlobalRef(customObj);
6.JVM:AttachCurrentThread/ DetachCurrentThread
#include <jni.h>
#include <stdio.h>
#include <malloc.h>
#include "logUtils.h"
static JavaVM *jvm=NULL;
static jobject jobj_callback=NULL;
static jmethodID mid=NULL;
static int flag=-1;
static pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
//在加载库时执行;
jint JNI_OnLoad(JavaVM *vm,void *reserved){
jvm=vm;
LOGE("------- JNI_OnLoad -------");
return JNI_VERSION_1_6;
}
//在卸载库时执行
void JNI_OnUnload(JavaVM *vm,void *reserved){
jvm=NULL;
LOGE("------- JNI_OnUnload -------");
}
//pthread中执行的函数
static void *nativeWork(void*args){
LOGE(" ==================== pre nativeWork ==================== ");
JNIEnv *env=NULL;
//附加到当前线程从JVM中取出JNIEnv, C/C++从子线程中直接回到Java里的方法时 必须经过这个步骤
if( (*jvm)->AttachCurrentThread(jvm,&env,NULL)==0 ){
while (flag==0){
if( jobj_callback==NULL ){
//进入等待
pthread_cond_wait(&cond,&mutex);
} else{
//回调java中的线程
(*env)->CallVoidMethod(env,jobj_callback,mid);
(*env)->DeleteGlobalRef(env,jobj_callback);
jobj_callback=NULL;
}
}
//完毕-脱离当前线程
(*jvm)->DetachCurrentThread(jvm);
}
LOGE(" ==================== end nativeWork ==================== ");
return (void*)1;
}