Android jni/ndk编程四:jni引用类型
来源:互联网 发布:娱乐圈明星爆料知乎 编辑:程序博客网 时间:2024/06/08 15:58
在前面的文章中,总结了jni的数据类型转换和c/c++访问java中的方法和字段的相关知识。这一届主要探究Jni的引用类型。
我们知道引用类型可以分为两种:opaque reference和plain reference。它们的区别在于我们是否知道引用所指向对象的细节和怎么获取到引用所指向的对象。
一.JNI引用类型
JNI支持三种类型的 opaque reference:local references, global references,和weak global references,下面我们将逐一探讨。
local references
大部分JNI 函数都会创建LocalRef,如NewObject创建一个实例,并返回一个指向该实例的LocalRef。LocalRef只在本线程的 native method中有效. 一但native method返回,LocalRef 将被释放。这意味着我们不能缓存LocalRef来提高效率,因为native方法一旦返回,LocalRef将被释放,缓存起来也没有用。
我们已经知道了大部分JNI函数都会创建LocalRef,比如NewObject,FindClass等,与创建相对应的,我们可以有两种方式让LocalRef 无效:
- native method返回,JavaVM自动释放LocalRef;
- 用DeleteLocalRef 主动释放。
DeleteLocalRef的定义如下:
void (*DeleteLocalRef)(JNIEnv*, jobject);
DeleteLocalRef 主动释放LocalRef是有意义的,如果我们内存特别紧张,而一个本地的方法有很多很耗内存的LocalRef,这个时候,在本地方法中及时释放这些LocalRef可以缓解内存压力。
LocalRef只在创建该对象的线程中有效,因此我们无法在其他线程中使用共享LocalRef.
Global References
Global引用类似于全局变量,我们可以在多个native方法中使用,也可以在多个线程中使用。此外,Golbal引用会阻止GC回收。但是,与c总的全局变量不同的是,Golbal引用必须通过特定的函数手动创建和释放。以下是相关函数的定义:
jobject (*NewGlobalRef)(JNIEnv*, jobject); void (*DeleteGlobalRef)(JNIEnv*, jobject);
使用举例:
//1.首先定义一个静态变量存储Global引用static jclass stringClass = NULL;//2.获得Local 引用jclass localRefCls = (*env)->FindClass(env,"java/lang/String");if (localRefCls == NULL) {return NULL; /* exception thrown */}//3.使用那个local引用创建全局引用stringClass = (*env)->NewGlobalRef(env, localRefCls);//4.及时释放Local引用(*env)->DeleteLocalRef(env, localRefCls);
以上是常见的、简单的创建Global引用的代码流程,使用完以后,记得把它释放掉,不然后内存泄漏了,因为Global引用是阻止GC的。
Weak Global References
所谓弱全局引用就是全局引用的另一个版本,既然它是全局引用,那么它就具备了在多个线程中共享的能力,以及我们可以在单个线程的不同函数中都可以使用它。之所以说它弱是因为它无法阻止GC。前面我们说Global引用很强势,它只能手动释放,JVM虚拟机不能自动GC它,但是Weak Global就会被垃圾回收器回收,这就是它若的原因。
Weak Global Ref用 NewGlobalWeakRef于DeleteGlobalWeakRef进行创建和删除,多个本地方法调用过程中和多线程上下文中使用的特性与 GlobalRef相同。这两个函数在jni.h中的定义如下:
jweak (*NewWeakGlobalRef)(JNIEnv*, jobject); void (*DeleteWeakGlobalRef)(JNIEnv*, jweak);
我们看到这里又出现了一个新的类型:jweak,它其实就是jobject,只是名字不容而已:
typedef jobject jweak;
用法举例:
static jclass string= NULL;if (string == NULL) { jclass local_string = (*env)->FindClass(env, "java/lang/String"); if (myCls2Local == NULL) { return; /* can’t find class */ } string = NewWeakGlobalRef(env, local_string ); if (myCls2 == NULL) { return; /* out of memory */ }}
由于Weak Global引用可能被垃圾回收器回收,所以我们在使用它之前一定要判断它是否为空。如果空的话需要重新创建它,不为空就继续使用。
二.Comparing Reference
既然我们可以有多个引用,它可能是全局引用,弱全局引用或局部引用,我们怎么判断它是不是同一个引用呢?不用急,JNI已经为我们提供好了函数,我们可以直接用,其定义如下:
jboolean (*IsSameObject)(JNIEnv*, jobject, jobject);
如果相通,返回JNI_TRUE, 否则返回JNI_FALSE。
三.引用管理
引用管理是为了较少内存使用,提高代码效率。JNI支持的三种引用各有各得用途,绝不能滥用。笔者水平有限,就不多废话了,这里主要讲一下Local引用的管理。
JNI提供了一组管理Local引用的函数:
jint (*PushLocalFrame)(JNIEnv*, jint); jobject (*PopLocalFrame)(JNIEnv*, jobject);
在进入本地方法时,调用一次
PushLocalFrame,并在本地方法结束时调用 PopLocalFrame. 此对方法执行效率非常高,建议使用这对方法。
一定保证该上下文出口只有一个,或每个return语句都做严格检查是否调用了PopLocalFrame。因为如果忘记调用PopLocalFrame 可能会使JVM崩溃。
用法举例:
jobject hello(JNIEnv *env, jobject obj){jobject result;//进入函数后pushif ((*env)->PushLocalFrame(env, 10) < 0) {/* frame not pushed, no PopLocalFrame needed */return NULL;}...result = ...;if (...) {//认真检查每一个函数的出口,绝不能忘记PopLocalFrameresult = (*env)->PopLocalFrame(env, result);return result;}...//正常返回前pop一下result = (*env)->PopLocalFrame(env, result);return result;}
- Android jni/ndk编程四:jni引用类型
- Android JNI + NDK 编程
- Android Stuido Ndk-Jni 开发(四):Jni打包及引用aar
- Android Stuido Ndk-Jni 开发(四)Jni打包及引用aar
- Android JNI NDK 编程学习
- Android NDK 开发(四)JNI 中局部引用、全局引用和弱全局引用
- Android进阶专题四:NDK JNI数据类型
- Android NDK(四):JNI 数组
- android(NDK+JNI)---JNI数据类型
- Android jni/ndk编程五:jni异常处理
- android ndk jni 编程入门例子
- Android NDK编程之JNI探究
- android ndk jni 编程入门例子
- Android Studio JNI NDK编程(一)
- Android-JNI和NDK编程【占坑中】
- Android Studio NDK开发--JNI编程
- Android Studio NDK,JNI编程入门
- Android中的JNI和NDK编程实践
- C#21课的内容
- 二分法递归写法
- 《Learn You Some Erlang for Great Good!》的学习笔记(九)
- tabAcitivity实现多页面效果(学生的滴滴矿车项目)
- word2vec 中的数学原理详解(一)目录和前言
- Android jni/ndk编程四:jni引用类型
- windows中Apache下vhosts.conf中配置301重定向
- javaMail发送邮件(工具类开发)
- 算法学习第一章-----排序算法
- 离散数学代码实现 二元关系的可传递性判断
- ubuntu14.04下安装Matlab2014a
- 算法学习第二章-----查找算法
- Android组件---四大布局的属性详解
- 去哪儿校招现场面面经