国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

JNI資源釋放

2019-11-14 11:07:59
字體:
供稿:網(wǎng)友

JNI 編程實(shí)現(xiàn)了 native code 和 java 程序的交互,因此 JNI 代碼編程既遵循 native code 編程語言的編程規(guī)則,同時(shí)也遵守 JNI 編程的文檔規(guī)范。在內(nèi)存管理方面,native code 編程語言本身的內(nèi)存管理機(jī)制依然要遵循,同時(shí)也要考慮 JNI 編程的內(nèi)存管理。

本章簡(jiǎn)單概括 JNI 編程中顯而易見的內(nèi)存泄漏。從 native code 編程語言自身的內(nèi)存管理,和 JNI 規(guī)范附加的內(nèi)存管理兩方面進(jìn)行闡述。

Native Code 本身的內(nèi)存泄漏

JNI 編程首先是一門具體的編程語言,或者 C 語言,或者 C++,或者匯編,或者其它 native 的編程語言。每門編程語言環(huán)境都實(shí)現(xiàn)了自身的內(nèi)存管理機(jī)制。因此,JNI 程序開發(fā)者要遵循 native 語言本身的內(nèi)存管理機(jī)制,避免造成內(nèi)存泄漏。以 C 語言為例,當(dāng)用 malloc() 在進(jìn)程堆中動(dòng)態(tài)分配內(nèi)存時(shí),JNI 程序在使用完后,應(yīng)當(dāng)調(diào)用 free() 將內(nèi)存釋放。總之,所有在 native 語言編程中應(yīng)當(dāng)注意的內(nèi)存泄漏規(guī)則,在 JNI 編程中依然適應(yīng)。

Native 語言本身引入的內(nèi)存泄漏會(huì)造成 native memory 的內(nèi)存,嚴(yán)重情況下會(huì)造成 native memory 的 out of memory。

Global Reference 引入的內(nèi)存泄漏

JNI 編程還要同時(shí)遵循 JNI 的規(guī)范標(biāo)準(zhǔn),JVM 附加了 JNI 編程特有的內(nèi)存管理機(jī)制。

JNI 中的 Local Reference 只在 native method 執(zhí)行時(shí)存在,當(dāng) native method 執(zhí)行完后自動(dòng)失效。這種自動(dòng)失效,使得對(duì) Local Reference 的使用相對(duì)簡(jiǎn)單,native method 執(zhí)行完后,它們所引用的 Java 對(duì)象的 reference count 會(huì)相應(yīng)減 1。不會(huì)造成 Java Heap 中 Java 對(duì)象的內(nèi)存泄漏。

而 Global Reference 對(duì) Java 對(duì)象的引用一直有效,因此它們引用的 Java 對(duì)象會(huì)一直存在 Java Heap 中。程序員在使用 Global Reference 時(shí),需要仔細(xì)維護(hù)對(duì)Global Reference 的使用。如果一定要使用 Global Reference,務(wù)必確保在不用的時(shí)候刪除。就像在 C 語言中,調(diào)用 malloc() 動(dòng)態(tài)分配一塊內(nèi)存之后,調(diào)用 free()釋放一樣。否則,Global Reference 引用的 Java 對(duì)象將永遠(yuǎn)停留在 Java Heap 中,造成 Java Heap 的內(nèi)存泄漏。

 

 

1、什么需要釋放? 

什么需要什么呢 ? JNI 基本數(shù)據(jù)類型是不需要釋放的 , 如 jint , jlong , jchar 等等 。 我們需要釋放是引用數(shù)據(jù)類型,當(dāng)然也包括數(shù)組家族。如:jstring,jobject ,jobjectArray,jintArray 等等。

當(dāng)然,大家可能經(jīng)常忽略掉的是 jclass ,jmethodID , 這些也是需要釋放的哦

 

2、如何去釋放?

1)      釋放String

jstring jstr = NULL;

char* cstr = NULL;

//調(diào)用方法

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)      釋放 類 、對(duì)象、方法

(*jniEnv)->DeleteLocalRef(jniEnv, XXX);

 

“XXX” 代表 引用對(duì)象

3)      釋放 數(shù)組家族

jobjectArray arrays = 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數(shù)組

 

   

 

native method 調(diào)用 DeleteLocalRef() 釋放某個(gè) JNI Local Reference 時(shí),首先通過指針 p 定位相應(yīng)的 Local Reference 在 Local Ref 表中的位置,然后從Local Ref 表中刪除該 Local Reference,也就取消了對(duì)相應(yīng) Java 對(duì)象的引用(Ref count 減 1)。

 

 

       參考文章:在 JNI 編程中避免內(nèi)存泄漏

一、多次NewByteArray后,報(bào)錯(cuò)“ReferenceTable overflow”

解決辦法:釋放所有對(duì)object的引用

例: jbyteArray audioArray = jnienv->NewByteArray(frameSize);       jnienv->SetByteArrayRegion(audioArray,0,frameSize,(jbyte*)fReceiveBuffer);       jnienv->DeleteLocalRef(audioArray);

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

jbyte* array= (*env)->GetByteArrayElements(env,jarray,&isCopy);(*env)->ReleaseByteArrayElements(env,jarray,array,0);

 

5.const char* input =(*env)->GetStringUTFChars(env,jinput, &isCopy);

(*env)->ReleaseStringUTFChars(env,jinput,input);

 

6.NewGlobalRef/DeleteGlobalRef

 jobject     (*NewGlobalRef)(JNIEnv*, jobject);     void        (*DeleteGlobalRef)(JNIEnv*, jobject);

例如,

jobject ref= env->NewGlobalRef(customObj);env->DeleteGlobalRef(customObj);
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 商河县| 老河口市| 临高县| 阿拉善盟| 东乌珠穆沁旗| 高淳县| 四子王旗| 濮阳县| 错那县| 灵寿县| 贡觉县| 晴隆县| 铜鼓县| 五大连池市| 株洲市| 承德市| 六安市| 石柱| 南京市| 措美县| 财经| 张北县| 稻城县| 虞城县| 庆阳市| 金寨县| 赤峰市| 连云港市| 海安县| 手游| 米泉市| 隆子县| 松原市| 长宁区| 武鸣县| 庆阳市| 临泽县| 固原市| 三都| 沙坪坝区| 宜春市|