Android NDK学习笔记5:引用类型管理

转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/119545225
本文出自【赵彦军的博客】

在 JNI 中,有三种引用类型

  • 全局引用
  • 局部引用
  • 弱引用

局部引用

在方法中定义的局部引用,可以不用手动释放,在程序运行结束后,会自动释放。但是有一种情况,比如在方法中有 for 循环,如果产生大量的局部引用,会占用大量内存。所以一种比较好的编程习惯就是,产生的局部变量,一旦不再使用,就手动释放一下。

void DeleteLocalRef(jobject localRef)

举例说明:

extern "C"
JNIEXPORT void JNICALL
Java_com_example_myapplication_MainActivity_run(JNIEnv *env, jobject thiz) {
    jstring str = env->NewStringUTF("string");
    //释放局部变量
    env->DeleteLocalRef(str);
}

全局引用

顾名思义,全局引用就是生命周期特别长,方法结束后不会自动释放内存。

创建全局变量:

jobject NewGlobalRef(jobject obj)

举个例子:

extern "C"
JNIEXPORT void JNICALL
Java_com_example_myapplication_MainActivity_run(JNIEnv *env, jobject thiz) {
    static jclass strClass = nullptr;
    if (strClass == nullptr) {
        //创建局部变量
        jclass cls = env->FindClass("java/lang/String");
        //全局引用赋值
        strClass = static_cast<jclass>(env->NewGlobalRef(cls));
        //释放局部引用
        env->DeleteLocalRef(cls);
    } else {
       //使用全局变量
    }
}

需要注意的是 ,static 不能修饰局部变量,因为局部变量在程序退出的时候,会自动释放。那么 static 修饰的变量就变成了野指针。

释放全局引用

void DeleteGlobalRef(jobject globalRef)

举例说明:

extern "C"
JNIEXPORT void JNICALL
Java_com_example_myapplication_MainActivity_run(JNIEnv *env, jobject thiz) {
    static jclass strClass = nullptr;
    if (strClass == nullptr) {
        //创建局部变量
        jclass cls = env->FindClass("java/lang/String");
        //全局引用赋值
        strClass = static_cast<jclass>(env->NewGlobalRef(cls));
        //释放局部引用
        env->DeleteLocalRef(cls);
    } else {
       //使用全局变量
    }
    //释放全局引用
    env->DeleteGlobalRef(strClass);
}

弱引用

弱引用的定义和java 弱引用的定义是一样的。
全局引用不会被 GC , 但是弱引用会在内存不足的情况下,被GC。所以在使用 弱引用之前要判断一下该引用是否被GC 。

判断方法:

jboolean IsSameObject(jobject ref1, jobject ref2)

举例说明:

extern "C"
JNIEXPORT void JNICALL
Java_com_example_myapplication_MainActivity_run(JNIEnv *env, jobject thiz) {
    static jclass strClass = nullptr;
    if (strClass == nullptr) {
        //创建局部变量
        jclass cls = env->FindClass("java/lang/String");
        //弱引用赋值
        strClass = static_cast<jclass>(env->NewWeakGlobalRef(cls));
        //释放局部引用
        env->DeleteLocalRef(cls);
    } else {
       
    }
    
    //判断是否被GC
    bool isGC = env->IsSameObject(strClass, nullptr);
    if (isGC) {
        //弱引用被回收了
    } else {
        //弱引用没有被回收
    }

    //释放全局引用
    env->DeleteWeakGlobalRef(strClass);
}

总结

  • 1、全局引用可以做缓存,对象复用。可以避免频繁的创建对象
  • 2、弱引用会在内存不足的情况下被回收,所以弱引用在使用之前要判断是否为 Null
  • 3、局部引用会在方法结束时自动释放,如果有循环频繁创建局部引用,会占用大量内存,需要手动释放
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值