百度了一下,google了一下,關於NDK引用的介紹無10篇中就有9.9篇是相同的,對於這種問題,我只能嗚呼哀哉了!!java
局部引用(函數內部對象類型變量):在C或C++中,局部變量表示只運行範圍侷限在該變量最近的 「{}」花括號裏,常見的就是函數中的變量了,但局部引用和局部變量不一樣了,引用的主體是對象,指針,android
所以,設涉及到內存回收問題。同局部變量同樣,局部對象在函數執行完成後會被當即銷燬。緩存
(錯誤的用法1:將局部引用賦值給全局引用或弱引用)函數
(錯誤的用法 : 引用被靜態緩存,這種方法十分危險,容易致使程序蹦退,但不是不能夠,只是引用的主題必須不是對象才行,好比jfieldID,jmethodID等)google
JNIEXPORT void JNICALL Java_com_ndk_cjava_exchange_UserEntity_referenceUnit (JNIEnv * env, jobject thiz) { static jfieldID nameField = NULL; if(nameField==NULL) { nameField = env->GetFieldID(clazz,"name","Ljava/lang/String;"); } //do somthing }
全局引用(函數外部對象類型變量):全局引用表示把局部引用經過某種方式複製給全局對象,而且該變量不會自動銷燬,須要手動銷燬spa
jclass globalJclazz = NULL; JNIEXPORT void JNICALL Java_com_ndk_cjava_exchange_UserEntity_referenceUnit (JNIEnv * env, jobject thiz) { if(globalJclazz==NULL) { __android_log_print(ANDROID_LOG_INFO,"REF","--1-->"); globalJclazz = (jclass)(env->NewGlobalRef(env->GetObjectClass(thiz))); //轉爲全局引用 }else{ __android_log_print(ANDROID_LOG_INFO,"REF","--2-->"); env->DeleteGlobalRef(globalJclazz); globalJclazz =NULL; } }
弱引用:做用域同全局變量同樣,但不能保證該引用一致從在,當內存不足時會自動銷燬指針
jclass weakclass = NULL; JNIEXPORT void JNICALL Java_com_ndk_cjava_exchange_UserEntity_referenceUnit (JNIEnv * env, jobject thiz) { if(weakclass==NULL || (env->IsSameObject(weakclass,NULL))==JNI_TRUE) { jclass jclzz = env->GetObjectClass(thiz); weakclass = (jclass)(env->NewWeakGlobalRef(jclzz)); }else{ env->DeleteWeakGlobalRef(weakclass); weakclass = NULL; } }