JNI学习笔记:引用技术

这篇博客详细介绍了JNI中的引用类型,包括局部引用、全局引用和弱引用的创建、生命周期及释放。局部引用在本地方法返回后自动释放,全局引用需要手动释放,弱引用允许对象被GC回收。文章还讨论了引用管理的重要性,防止内存泄漏和引用错误。
摘要由CSDN通过智能技术生成


1 前言

1.1 什么是引用

  在使用JNI技术进行Java和Native代码的混编的时候,不可避免的要大量使用JNI提供的一些实例和数组类型(jobject、jclass、jstring、jarray等),而对这些类型的操作,往往不是通过该类类型变量本身进行的,而是通过使用JNI操作一个不透明的引用来间接的操作数据内容因为只操作引用而不牵涉类型具体本身的内容,所以不必担心依赖于特定Java虚拟机实现的内部对象分布。这一机制无疑提高了程序运行效率,也增加了我们的学习内容。引用的产生随处可见,常见的,如FindClassNewObject 等函数都会自动产生一个指向JVM内部数据的引用。

1.2 为什么要使用引用

  引用这个机制在JNI编程中广泛出现,我们必须了解其工作原理和使用规范,才能够更好的去使用这一机制,进而保证我们的代码更加健壮、高效。尤其是在频繁的JNI交互的缓存技术中,使用好引用机制,有利于减少不必要的引用累积、不安全的引用访问以及更好的内存管理,保障程序不会在JNI内部崩溃
  本文主要参考了《JNI编程规范》一书中第五章节的内容进行整理和学习。

2. 全局引用和局部引用

  JNI支持三种不同的引用:局部引用(local references)、全局引用(global references)和弱全局引用(weak global references

  • 局部引用和全局引用的生命周期不同,当本地方法返回时,局部引用会被自动释放,而全局引用和弱全局引用则需要手动释放。
  • 局部引用和全局引用会阻止GC(Garbage collection)回收它们所引用的对象(注意是引用的对象,不是引用本身),但是弱引用不会。

2.1 局部引用

  大多数JNI函数会创建局部引用,例如,NewObject 函数创建一个对象实例并返回这个对象的局部引用。局部引用只有在创建它的本地方法返回之前有效,本地方法返回之后,局部引用会自动释放(这一点类似于局部变量的生命周期)。因此,不能在局部方法中把局部引用存储为静态变量缓存起来以供下次使用。
  下面是一个局部引用的错误使用例子:

/* 以下代码存在错误 */
jstring
MyNewString(JNIEnv *env, jchar *chars, jint len)
{
    static jclass stringClass = NULL;
    jmethodID cid;
    jcharArray elemArr;
    jstring result;
    if (stringClass == NULL) {
        stringClass = (*env)->FindClass(env,"java/lang/String");
        if (stringClass == NULL) {
            return NULL; /* 抛出异常 */
        }
    }
    /* 此处使用缓存的变量stringClass可能错误,
    因为局部引用已被释放,此时的stringClass内容非法*/
    cid = (*env)->GetMethodID(env, stringClass,"<init>", "([C)V");
    ...
    elemArr = (*env)->NewCharArray(env, len);
    ...
    result = (*env)->NewObject(env, stringClass, cid, elemArr);
    (*env)->DeleteLocalRef(env,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值