[关闭]
@cxm-2016 2016-11-15T15:26:12.000000Z 字数 2113 阅读 7281

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

JNI完全指南

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

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


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



三、引用类型

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

3.1 全局引用

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

3.1.1 新建全局引用

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

jobject NewGlobalRef(JNIEnv *env, jobject obj);

  • obj:任意类型的引用。
  • return:全局引用。如果内存不足返回NULL。

3.1.2 删除全局引用

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

void DeleteGlobalRef(JNIEnv *env, jobject globalRef);

  • globalRef:全局引用。

3.2 局部引用

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

3.2.1 创建局部引用

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

jobject NewLocalRef(JNIEnv *env, jobject ref);

  • ref:全局或者局部引用
  • return:局部引用

3.2.2 删除局部引用

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

void DeleteLocalRef(JNIEnv *env, jobject localRef);

  • localRef:局部引用。

3.2.3 确认局部引用容量

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

jint EnsureLocalCapacity(JNIEnv *env, jint capacity);

  • capacity:给定局部引用的数量。
  • return:JNI_OK表示当前线程栈可以创建capacity个局部引用。返回其他值表示不可用,并抛出一个OutOfMemoryError异常

存在异常

  • OutOfMemoryError

3.2.4 局部栈帧的入栈和出栈

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

3.3 弱全局引用

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

3.3.1 新建弱全局引用

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

jweak NewWeakGlobalRef(JNIEnv *env, jobject obj);

  • obj:任意对象。
  • return:返回弱全局引用,如果obj为NULL则返回NULL。

3.3.2 删除弱全局引用

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

void DeleteWeakGlobalRef(JNIEnv *env, jweak obj);

  • obj:弱全局引用。

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


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

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注