JNI記憶體洩露處理方法彙總
阿新 • • 發佈:2019-01-09
在c++中new的物件,如果不返回java,必須用release掉,否則記憶體洩露。包括NewStringUTF,NewObject。如果返回java不必release,java會自己回收。
記憶體洩露可以先從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
2.NewString / NewStringUTF / NewObject / NewByteArray
例如,
env->DeleteLocalRef(ref);
3.GetObjectField/GetObjectClass/GetObjectArrayElement
4.GetByteArrayElements和GetStringUTFChars
5.NewGlobalRef/DeleteGlobalRef
例如,
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
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);