【Android NDK 开发】JNI 引用 ( 局部引用 | 局部引用作用域 | 局部引用产生 | 局部引用释放 | 代码示例)

简介: 【Android NDK 开发】JNI 引用 ( 局部引用 | 局部引用作用域 | 局部引用产生 | 局部引用释放 | 代码示例)

文章目录

I . JNI 引用数据类型

II . JNI 引用 与 指针

III . 局部引用 作用域

IV . 局部引用 产生 与 释放

V . 局部引用 代码示例



I . JNI 引用数据类型


1 . JNI 引用类型 : JNI 中 定义了 八种 Java 基本数据类型 , 其余的 jobject , jarray , jxxxArray , jclass , jstring 等都是引用类型 ;



① 规律 : 除 八种 基本数据类型之外的都是引用数据类型 ;


② 都是 Java 引用数据类型 : 这些数据类型都是 C/C++ 中定义的 Java 引用数据类型 , 其本质是 C/C++ 环境中对应的 Java 数据类型 ;



要注意将 JNI 中的 Java 类型引用 , 与 C/C++ 指针区分开 , 两者概念不同 ;



2 . JNI 引用类型分为三类 :



① 局部引用 : 其只在作用域内有效 , 内存不可回收 ;


② 全局引用 : 全局有效 , 内存不可回收 ;


③ 全局弱引用 : 全局有效 , 内存不足时会被 JVM 回收 ;



内存不可回收 , 如果内存不足 , 会直接 OOM 内存溢出 ;




II . JNI 引用 与 指针


在 JNI 中一定要将 引用 和 指针 区分开 ;


引用 是 Java 语言中的概念 , 指针 是 C/C++ 中的概念 ;


JNI 中 Java 引用类型 也是使用 C/C++ 指针表示的 , 这个 变量 就有了 两重含义 , 即代表 Java 中的引用类型 , 又代表了 编程环境中的 指针 ;


这里注意 , 如果引用被 JVM 释放了 , 即使指针还有值 , 也是不能用于 JNI 中与 Java 引用类型 相关的方法的 ;



本博客只讨论引用相关的内容 ;




III . 局部引用 作用域


1 . 局部引用作用域 :



局部引用只能在当前作用域有效 ;


超出作用域

手动释放

上面 两种情况 都会导致 局部引用变量 失效 ;



2 . 局部引用作用范围 :


① 空间 : 不能 跨线程 , 跨方法调用 , 仅在本作用域有效 ;


② 时间 : 创建后可以使用 , 手动释放 或 作用域结束 引用被释放不可使用 ;




IV . 局部引用 产生 与 释放


1 . 局部引用产生 与 释放 :


① 局部引用产生 : 使用 NewXXX / FindXXX 等 大多数 JNI 方法 默认创建的 Java 引用类型对象 都是局部引用 ;


② 局部引用释放 : 调用 DeleteLocalRef 方法 释放该局部引用 ;



2 . 局部引用的两种释放方式 :



① 自动释放 : 在方法作用域结束后 , JVM 自动释放上述 局部引用 变量 ;


② 手动释放 : 通过调用 DeleteLocalRef 方法手动释放 ;



3 . 局部引用推荐释放方式 :



① 内存角度考虑 : 局部引用 释放尽量灵活 , 不要等待自动释放 , 在使用完毕后 建议就手动释放 , 尽早回收内存 ;


② 自动释放情况 :如果该 引用 一直到最后都要使用 , 那么可以不进行手动释放 ;


③ 建议用法 : 局部引用建议都要手动释放 , 哪怕是在作用域最后 , 也要进行手动释放




V . 局部引用 代码示例


局部引用代码示例 :


extern "C"
JNIEXPORT void JNICALL
Java_kim_hsl_jni_MainActivity_jniLocalReferenceTest(JNIEnv *env, jobject instance) {
    /*
        局部引用
            局部引用只能在当前作用域有效
                超出作用域
                手动释放
            上面 两种情况 都会导致 该局部变量都会失效
        局部引用作用范围 :
                空间 : 不能 跨线程 , 跨方法调用 , 仅在本作用域有效
                时间 : 创建后可以使用 , 手动释放 或 作用域结束 引用被释放不可使用
        局部引用 创建 : 使用 NewXXX / FindXXX 等 大多数 JNI 方法 默认创建的都是局部引用
                释放 : 调用 DeleteLocalRef 方法 释放该局部引用
        关于上面的三个创建的 局部引用 有两种释放方式
            方式一 : 在方法作用域结束后 , VM 自动释放上述变量
            方式二 : 通过调用 DeleteLocalRef 方法手动释放
        建议使用方式二 :
            局部引用 释放尽量灵活 , 不要等待自动释放 , 在使用完毕后 建议就手动释放 , 今早回收内存
            如果该 引用 一直到最后都要使用 , 那么可以不进行手动释放 ;
            建议用法 : 局部引用建议都要手动释放 , 哪怕是在作用域最后 , 也要进行手动释放
        局部引用传递到 Java 层 , 该传递是拷贝传递 , JNI 中该释放还是释放 , 不影响 Java 层使用
        引用概念 :
            这里要将 引用 和 指针的概区分清楚 ;
            class_teacher 引用在 作用域结束时 会被释放 , 不能将其用于 JNI 反射 Java 类的方法和字段
                          其指针值不为空 , 仍然有值 , 其仍然指向一个地址 , 但是地址中的数据被释放了
     */
    // 1 . 获取 Teacher 类 ( 该变量需要释放 )
    jclass class_teacher = env->FindClass("kim/hsl/jni/Teacher");
    // 2 .  查找构造方法
    jmethodID method_init = env->GetMethodID(class_teacher, "<init>", "(ILjava/lang/String;)V");
    // 3 . 准备 Java 类型参数 ( 该变量需要释放 )
    //     此处特别注意 : 传入到 Java 方法中的参数都必须是 Java 参数
    jint teacher_age = 88;
    jstring teacher_name = env->NewStringUTF("Tom Wang");
    // 4 .  创建 Teacher 对象 ( 该变量需要释放 )
    jobject teacher = env->NewObject(class_teacher, method_init, teacher_age, teacher_name);
    // 5 .  释放上面通过 FindClass NewStringUTF NewObject 创建的引用变量 , 否则会造成内存泄漏
    //     使用完这三个引用之后 , 不再使用 ; 这里特别建议手动释放三个引用
    //     如果不手动释放 , 在 该引用 作用域 结束后 , 也会自动释放掉
    env->DeleteLocalRef(teacher_name);
    env->DeleteLocalRef(teacher);
    env->DeleteLocalRef(class_teacher);
}



目录
打赏
0
0
0
0
39
分享
相关文章
Termux安卓终端美化与开发实战:从下载到插件优化,小白也能玩转Linux
Termux是一款安卓平台上的开源终端模拟器,支持apt包管理、SSH连接及Python/Node.js/C++开发环境搭建,被誉为“手机上的Linux系统”。其特点包括零ROOT权限、跨平台开发和强大扩展性。本文详细介绍其安装准备、基础与高级环境配置、必备插件推荐、常见问题解决方法以及延伸学习资源,帮助用户充分利用Termux进行开发与学习。适用于Android 7+设备,原创内容转载请注明来源。
311 76
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
87 8
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
78 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
escrcpy:【技术党必看】Android开发,Escrcpy 让你无线投屏新体验!图形界面掌控 Android,30-120fps 超流畅!🔥
escrcpy 是一款基于 Scrcpy 的开源项目,使用 Electron 构建,提供图形化界面来显示和控制 Android 设备。它支持 USB 和 Wi-Fi 连接,帧率可达 30-120fps,延迟低至 35-70ms,启动迅速且画质清晰。escrcpy 拥有丰富的功能,包括自动化任务、多设备管理、反向网络共享、批量操作等,无需注册账号或广告干扰。适用于游戏直播、办公协作和教育演示等多种场景,是一款轻量级、高性能的 Android 控制工具。
142 1
彻底理解引用在 Android 和 Java 中的工作原理
本文讲的是彻底理解引用在 Android 和 Java 中的工作原理,几周前,我很荣幸地参加了在波兰举行的 Mobiconf ,移动开发者参加的最好的研讨会之一。我的朋友兼同事 Jorge Barroso 做了个名为“最好(良好)的做法”的演说 ,这让我在听后很有感触:
1622 0
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
231 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
192 12
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
78 1
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
100 19
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
146 14