美文网首页Android知识Android技术知识
JNI完全指南(三)——引用类型

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

作者: 798fe2ac8685 | 来源:发表于2016-11-15 15:24 被阅读107次

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

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

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


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


    [toc]


    三、引用类型

    在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

    相关文章

      网友评论

        本文标题:JNI完全指南(三)——引用类型

        本文链接:https://www.haomeiwen.com/subject/mtflpttx.html