Android知识Android技术知识

JNI完全指南(三)——引用类型

2016-11-15  本文已影响107人  798fe2ac8685

标签(空格分隔): JNI完全指南

版本:1
作者:陈小默
声明:禁止商业,禁止转载

发布于作业部落简书CSDN博客


前一篇:JNI完全指南(二)——类与异常


[toc]


三、引用类型

在JNI中引用类型分为三种,分别是全局引用,局部引用和弱全局引用。

3.1 全局引用

全局引用可以跨方法(本地方法返回后仍然有效),跨线程使用,直到手动释放才会失效。该引用不会被GC回收。

3.1.1 新建全局引用

通过以下方法可以将任意引用转换为全局引用。由于全局引用不再受到JVM统一管理,所以我们要在不用时手动删除。

jobject NewGlobalRef(JNIEnv *env, jobject obj);

3.1.2 删除全局引用

通过以下方法可以删除一个全局引用。

void DeleteGlobalRef(JNIEnv *env, jobject globalRef);


3.2 局部引用

局部引用是JVM负责的引用类型,其被JVM分配管理,并占用JVM的资源。局部引用在native方法返回后被自动回收。局部引用只在创建它们的线程中有效,不能跨线程传递。

3.2.1 创建局部引用

通过以下方法可以创建一个局部引用。通常情况下,我们在native方法中创建的引用都是局部引用,并且不需要手动进行释放,当方法返回时,这个引用就会被自动销毁。

jobject NewLocalRef(JNIEnv *env, jobject ref);

3.2.2 删除局部引用

通过以下方法可以删除一个局部引用。

void DeleteLocalRef(JNIEnv *env, jobject localRef);

3.2.3 确认局部引用容量

虚拟机将确保每个本地方法至少可以创建16个局部引用。但是在如今的场景中,16个局部引用已经远远不能满足开发需求了。为了为了解决这个问题,JNI提供了查询可用引用容量的方法,我们在创建超出限制的引用时最好先确认是否有足够的空间可以。

jint EnsureLocalCapacity(JNIEnv *env, jint capacity);

存在异常

3.2.4 局部栈帧的入栈和出栈

Push/PopLocalFrame函数对提供了对局部引用的生命周期更方便的管理。你可以在本地函数的入口处调用PushLocalFrame,然后在出口处调用PopLocalFrame,这样的话,在两个函数之间任何位置创建的局部引用都会被释放。而且,这两个函数是非常高效的。如果你在函数的入口处调用了PushLocalFrame,那么一定要在函数返回时调用PopLocalFrame。下面的方法用来创建并入栈一个能够保存一定数量数据引用的栈帧:

jint PushLocalFrame(JNIEnv *env, jint capacity);

我们可以调用如下方法弹出一个局部引用栈帧,并销毁其中的全部局部引用。

jobject PopLocalFrame(JNIEnv *env, jobject result);

异常


3.3 弱全局引用

弱全局引用是一种特殊的全局引用。跟普通的全局引用不同的是,一个弱全局引用允许Java对象被垃圾回收器回收。当垃圾回收器运行的时候,如果一个对象仅被弱全局引用所引用,则这个引用将会被回收。一个被回收了的弱引用指向NULL,开发者可以将其与NULL比较来判定该对象是否可用。

3.3.1 新建弱全局引用

可以通过如下方法新建一个弱全局引用。

jweak NewWeakGlobalRef(JNIEnv *env, jobject obj);

3.3.2 删除弱全局引用

可以使用如下方法删除一个弱全局引用。

void DeleteWeakGlobalRef(JNIEnv *env, jweak obj);


下一篇:JNI完全指南(四)——对象操作


参考文献:
[1]ORACLE guides for JNI——Chapter 4: JNI Functions

上一篇下一篇

猜你喜欢

热点阅读