在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; 内存泄露可以先从windows资源管理器中,看到随程序运行,内存不断增长的趋势,具体可以用hp jmeter检测。在运行程序时,加jvm参数 -Xrunhprof:heap=all,cutoff=0 ,生成java.hprof.txt,用jmeter打开,Metric -> Residual Objects (Count),可以看到未回收的对象,选中要查看的对象,点Mark记录下要查看的对象,Window -> New Window 打开新窗口,用Metric -> Reference Graph Tree,然后点Find Immediately可以看到对象被哪里引用。 总体原则:释放所有对object的引用 1.FindClass 例如, [color=red] jclass ref= (env)->FindClass("java/lang/String"); env->DeleteLocalRef(ref); [/color] 2.NewString/ NewStringUTF/NewObject/NewByteArray 例如, [color=red] 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*); [/color] env->DeleteLocalRef(ref); 3.GetObjectField/GetObjectClass/GetObjectArrayElement [color=red] jclass ref = env->GetObjectClass(robj); env->DeleteLocalRef(ref); [/color] 4.GetByteArrayElements和GetStringUTFChars [color=red] 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); [/color] 5.NewGlobalRef/DeleteGlobalRef jobject (*NewGlobalRef)(JNIEnv*, jobject); void (*DeleteGlobalRef)(JNIEnv*, jobject); 例如, [color=red] jobject ref= env->NewGlobalRef(customObj); env->DeleteGlobalRef(customObj); [/color] |
|