Android NDK 开发(四)JNI 中局部引用、全局引用和弱全局引用

转载:http://xuhaoblog.com/ndk/jni-4.html

前言

做过Java的朋友都知道,内存管理这一块是完全透明的,new一个类的实例时,只知道创建完这个类的实例后,会返回这个实例的一个引用,然后拿着这个引用去访问它的成员了(属性、方法),完全不用管JVM内部怎么实现的,如何为新建的对象申请内存,使用完之后如何释放内存,只需要知道有个垃圾回收器在处理这些事情就行了,然而,从Java虚拟机创建的对象传到C/C++代码时会产生引用,根据Java的垃圾回收机制,只要有引用存在就不回触发该引用所指向Java对象的垃圾回收;这些引用在JNI 中分为3种:全局引用(Global Reference)、局部引用 (Local Reference)、弱全局引用 (Week Global Reference) since JDK1.2。

正文

三种引用的区别

1、全局引用

全局引用可以跨方法、跨线程使用,直到被开发者显式释放。类似局部引用,一个全局引用在被释放前保证引用对象不被GC回收。和局部引用不同的是,没有那么多函数能够创建全局引用。能创建全局引用的函数只有 NewGlobalRef。以下例子说明了如何使用一个全局引用。

java native方法:

public native void createGlobalRef();

public native String getGlobalRef();

public native void deleteGlobalRef();

jni实现:

//全局引用

//共享(可以跨多个线程),手动控制内存使用

jstring global_str;

//创建

JNIEXPORT void JNICALL Java_com_study_jni_JniTest_createGlobalRef(JNIEnv *env, jobject jobj){

jstring obj = (*env)->NewStringUTF(env, "jni development is powerful!");

global_str = (*env)->NewGlobalRef(env, obj);

}

//获得

JNIEXPORT jstring JNICALL Java_com_study_jni_JniTest_getGlobalRef(JNIEnv *env, jobject jobj){

return global_str;

}

//释放

JNIEXPORT void JNICALL Java_com_study_jni_JniTest_deleteGlobalRef(JNIEnv *env, jobject jobj){

(*env)->DeleteGlobalRef(env, global_str);

}

2、局部引用

一个局部引用仅在创建它的native函数及该函数调用的函数中有效。在一个native函数执行期间创建的所有局部引用将在该函数返回时被释放,创建了大量的局部引用,占用了太多的内存,而且这些局部引用跟后面的操作没有关联性。

//模拟:循环创建数组

JNIEXPORT void JNICALL Java_com_study_jni_JniTest_localRef(JNIEnv *env, jobject jobj){

int i = 0;

for (; i < 5; i++){

//创建Date对象

jclass cls = (*env)->FindClass(env, "java/util/Date");

jmethodID constructor_mid = (*env)->GetMethodID(env, cls, "", "()V");

jobject obj = (*env)->NewObject(env, cls, constructor_mid);

//此处省略一百行代码...

//不在使用jobject对象了

//通知垃圾回收器回收这些对象

//释放局部引用

(*env)->DeleteLocalRef(env, obj);

//此处省略一百行代码...

}

}

上面代码中,省略了和我们无关紧要的代码,通过FindClass返回一个对java.util.Date对象的局部引用。

3、弱全局引用

节省内存,在内存不足时可以是释放所引用的对象,可以引用一个不常用的对象,如果为NULL,临时创建,弱全局引用使用NewGlobalWeakRef创建,使用DeleteGlobalWeakRef释放。下面简称弱引用。与全局引用类似,弱引用可以跨方法、线程使用。但与全局引用很重要不同的一点是,弱引用不会阻止GC回收它引用的对象,所以在使用时需要多加小心,它所引用的对象可能是不存在的或者已经被回收。

1.创建弱全局引用

用NewWeakGlobalRef函数对弱全局引用进行初始化,例如:

jclass weakGlobalcls

weakGlobalcls = (*env)->NewWeakGlobalRef(env,localclazz);

2.引用的比较

给定两个引用(不管是全局、局部还是弱全局引用),我们只需要调用IsSameObject来判断它们两个是否指向相同的对象。例如:(*env)->IsSameObject(env, obj1, obj2)

如果obj1和obj2指向相同的对象,则返回JNI_TRUE(或者1),否则返回JNI_FALSE(或者0)。有一个特殊的引用需要注意:NULL,JNI中的NULL引用指向JVM中的null对象。如果obj是一个局部或全局引用,使用(*env)->IsSameObject(env, obj, NULL) 或者 obj == NULL来判断obj是否指向一个null对象即可。但需要注意的是,IsSameObject用于弱全局引用与NULL比较时,返回值的意义是不同于局部引用和全局引用的。比如:

if(JNI_FALSE == (*env)->IsSameObject(env,weakGlobalcls,NULL)){

//TODO 对象未被回收,可以使用

}else{

//TODO 对象被垃圾回收器回收,不能使用

}

以上就是学习这jni 的三种引用的简单使用,相关的知识并没有深入详细的说明!O(∩_∩)O~~

本文由博主辛苦整理下来的笔记;

希望大家能够指点或提出宝贵意见,共同学习,谢谢!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容