@cxm-2016
2016-11-15T15:26:12.000000Z
字数 2113
阅读 7331
JNI完全指南
版本:1
作者:陈小默
声明:禁止商业,禁止转载
前一篇:JNI完全指南(二)——类与异常
在JNI中引用类型分为三种,分别是全局引用,局部引用和弱全局引用。
全局引用可以跨方法(本地方法返回后仍然有效),跨线程使用,直到手动释放才会失效。该引用不会被GC回收。
通过以下方法可以将任意引用转换为全局引用。由于全局引用不再受到JVM统一管理,所以我们要在不用时手动删除。
jobject NewGlobalRef(JNIEnv *env, jobject obj);
- obj:任意类型的引用。
- return:全局引用。如果内存不足返回NULL。
通过以下方法可以删除一个全局引用。
void DeleteGlobalRef(JNIEnv *env, jobject globalRef);
- globalRef:全局引用。
局部引用是JVM负责的引用类型,其被JVM分配管理,并占用JVM的资源。局部引用在native方法返回后被自动回收。局部引用只在创建它们的线程中有效,不能跨线程传递。
通过以下方法可以创建一个局部引用。通常情况下,我们在native方法中创建的引用都是局部引用,并且不需要手动进行释放,当方法返回时,这个引用就会被自动销毁。
jobject NewLocalRef(JNIEnv *env, jobject ref);
- ref:全局或者局部引用
- return:局部引用
通过以下方法可以删除一个局部引用。
void DeleteLocalRef(JNIEnv *env, jobject localRef);
- localRef:局部引用。
虚拟机将确保每个本地方法至少可以创建16个局部引用。但是在如今的场景中,16个局部引用已经远远不能满足开发需求了。为了为了解决这个问题,JNI提供了查询可用引用容量的方法,我们在创建超出限制的引用时最好先确认是否有足够的空间可以。
jint EnsureLocalCapacity(JNIEnv *env, jint capacity);
- capacity:给定局部引用的数量。
- return:JNI_OK表示当前线程栈可以创建capacity个局部引用。返回其他值表示不可用,并抛出一个OutOfMemoryError异常
存在异常
- OutOfMemoryError
Push/PopLocalFrame函数对提供了对局部引用的生命周期更方便的管理。你可以在本地函数的入口处调用PushLocalFrame,然后在出口处调用PopLocalFrame,这样的话,在两个函数之间任何位置创建的局部引用都会被释放。而且,这两个函数是非常高效的。如果你在函数的入口处调用了PushLocalFrame,那么一定要在函数返回时调用PopLocalFrame。下面的方法用来创建并入栈一个能够保存一定数量数据引用的栈帧:
jint PushLocalFrame(JNIEnv *env, jint capacity);
- capacity:给定局部引用的数量。
- return:JNI_OK表示当前线程栈可以创建capacity个局部引用。返回其他值表示不可用,并抛出一个OutOfMemoryError异常
我们可以调用如下方法弹出一个局部引用栈帧,并销毁其中的全部局部引用。
jobject PopLocalFrame(JNIEnv *env, jobject result);
- result:给定保存栈帧的引用,如果不需要前一个栈帧则可以传入NULL。
- return:前一个帧的引用。
异常
- OutOfMemoryError:
弱全局引用是一种特殊的全局引用。跟普通的全局引用不同的是,一个弱全局引用允许Java对象被垃圾回收器回收。当垃圾回收器运行的时候,如果一个对象仅被弱全局引用所引用,则这个引用将会被回收。一个被回收了的弱引用指向NULL,开发者可以将其与NULL比较来判定该对象是否可用。
可以通过如下方法新建一个弱全局引用。
jweak NewWeakGlobalRef(JNIEnv *env, jobject obj);
- obj:任意对象。
- return:返回弱全局引用,如果obj为NULL则返回NULL。
可以使用如下方法删除一个弱全局引用。
void DeleteWeakGlobalRef(JNIEnv *env, jweak obj);
- obj:弱全局引用。
下一篇:JNI完全指南(四)——对象操作