reverse_xiaoyu

忘记并不可怕,可怕的是你从来就都不知道!

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

JNI 函数(二)全局及局部引用

(一)、创建全局引用

函数原型:jobject NewGlobalRef(JNIEnv *env, object obj);

  给对象 obj 创建一个全局引用,obj 可以是全局或局部引用。全局引用必须通过 DeleteGlobalRef() 显示处理。

  参数:

    env:JNI 接口指针

    obj:object 对象

  返回:

    全局引用 jobject,如果内存溢出则返回 NULL

(二)、删除全局引用

函数原型:void DeleteGlobalRef(JNIEnv *env, jobject globalRef);

  删除全局引用

  参数:

    env:JNI 接口指针

    globalRef:需要被删除的全局引用

(三)、删除局部引用

  局部引用只在本地接口调用时的生命周期内有效,当本地方法返回时,它们会被自动释放。每个局部引用都会消耗一定的虚拟机资源,虽然局部引用可以被自动销毁,但是程序员也需要注意不要在本地方法中过度分配局部引用,过度分配局部引用会导致虚拟机在执行本地方法时内存溢出。

函数原型:void DeleteLocalRef(JNIEnv *env, jobject localRef);

  通过 localRef 删除局部引用

  参数:

    env:JNI 接口指针

    localRef:需要被删除的局部引用

  JDK/JRE 1.1 提供了上面的 DeleteLocalRef 函数,这样程序员就可以手动删除本地引用。

  从JDK/JRE 1.2 开始,提供可一组生命周期管理的函数,他们是下面四个函数。

(四)、设定局部变量的容量

函数原型:jint EnsureLocalCapacity(JNIEnv *env, jint capacity);

  在当前线程中,通过传入一个容量 capacity,,限制局部引用创建的数量。成功则返回 0,否则返回一个负数,并抛出一个 OutOfMemoryError。VM 会自动确保至少可以创建 16 个局部引用。

  参数:

    env:JNI 接口指针

    capacity:容量

  返回:

    成功返回 0,失败返回一个负数,并会抛出一个 OutOfMemoryError

  为了向后兼容,如果虚拟机创建了超出容量的局部引用。VM 调用 FatalError,来保证不能创建更多的本地引用。(如果是 debug 模式,虚拟机回想用户发出 warning,并提示创建了更多的局部引用,在 JDK 中,程序员可以提供 -verbose:jni 命令行选项来打开这个消息)

(五)、在老的上创建一个新的帧

函数原型:jint PushLocalFram(JNIEnv *env , jint capacity);

  在已经设置设置了局部变量容量的情况下, 重新创建一个局部变量容器。成功返回0,失败返回一个负数并抛出一个OutOfMemoryError异常。

  注意:当前的局部帧中,前面的局部帧创建的局部引用仍然是有效的

  参数:

    env:JNI 接口指针

    capacity:容量

(六)、释放一个局部引用

函数原型:jobject PopLocalFrame(JNIEnv *env, jobject result)

  弹出当前的局部引用帧,并且释放所有的局部引用。返回在之前局部引用帧与给定result对象对应的局部引用。如果不需要返回任何引用,则设置 result 为 NULL

  参数:

    env:JNI 接口指针

    result:需要释放的局部引用

(七)、创建一个局部引用

函数原型:jobject NewLocalRef(JNIEnv *env, jobject ref);

  创建一个引用自 ref 的局部引用。ref 可以是全局或者局部引用,如果 ref 为 NULL,则返回 NULL。

  参数:

    env:JNI 接口指针

    ref:可以试试局部引用也可以是全局引用。

(八)、弱全局引用

  弱全局引用是一种特殊的全局引用,不像一般的全局引用,一个弱全局引用允许底层 Java 对象能够被垃圾回收。弱全局引用能够应用在任何全局或局部引用被使用的地方。当垃圾回收器运行的时候,如果对象只被弱引用所引用时,它将释放底层变量。一个弱引用指向一个被释放的对象相当于等于 NULL。编程人员可以通过使用 isSampleObject 对比弱引用和 NULL 来检测一个弱全局应用是否指向一个被释放的对象。弱全局引用在 JNI 中是 Java 弱引用的一个简化版本,在 Java 平台 API 中有有效。

  当 Native 方法正在运行的时候,垃圾回收器可能正在工作,被弱引用所指向的对象可能在任何时候被释放。弱全局引用能够应用在任何全局引用所使用的地方,通常是不太适合那么做的,因为它们可能在不注意的时候编程 NULL。

  当 IsSampleObject 能够识别一个弱全局引用是不是指向一个被释放的对象,但是这不妨碍这个对象在被检测之后马上被释放。这就说明了,程序员不能依赖这个方法来识别一个弱全局引用是否能够在后续的 JNI 函数调用中被使用。

  如果想解决上述的问题,建议使用 JNI 函数 NewLocalRef 或者 NewGlobalRef 来用标准的全局也引用或者局部引用来指向相同的对象。如果这个独享已经被释放了这些函数会返回 NULL。否则会返回一个强引用(这样就可以保证这个对象不会被释放)。当不需要访问这个对象时,新的引用必须显式被删除。

  1、创建全局弱引用

函数原型:jweak NewWeakGlobalRef(JNIEnv *env,jobject obj);

  创建一个新的弱全局引用。如果 obj 指向 NULL,则返回 NULL。如果 VM 内存溢出,将会抛出异常 OutOfMemoryError。

  参数:

    env:JNI 接口指针

    obj:引用对象

  返回:

    全局弱引用

 

  2、删除全局弱引用

函数原型:void DeleteWeakGlobalRef(JNIEnv *env,jweak obj);

  VM 根据所给定的弱全局引用删除对应的资源。

  参数:

    env:JNI 接口指针

    obj:将删除的弱全局引

posted on 2020-12-16 21:58  Reverse-xiaoyu  阅读(758)  评论(0编辑  收藏  举报