news 2026/7/1 2:39:24

JNI 引用表——LocalRef / GlobalRef / WeakGlobalRef

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JNI 引用表——LocalRef / GlobalRef / WeakGlobalRef

JNI 引用到底是什么?

在 JNI 里你会看到这些类型:

jobject jclass jstring jarray jbyteArray jthrowable

它们看起来像 C++ 指针,但你不能把它们当普通指针理解。

更准确地说:它们是 Java 对象在 native 层的引用句柄。
native 代码不能直接操作 Java 对象内存,只能通过 JNIEnv 提供的接口间接访问。

比如

jstring name=env->NewStringUTF("hello");constchar*chars=env->GetStringUTFChars(name,nullptr);

jstring name只是一个对java中string类型的引用,要转换成c++的string得GetStringUTFChars

Local Reference:本地引用

LocalRef 是最常见的 JNI 引用。可以说你在native层看到的东西大部分都是LocalRef
例如

extern"C"JNIEXPORTvoidJNICALLJava_com_xxx_NativeBridge_nativeFoo(JNIEnv*env,jobject thiz){jstring str=env->NewStringUTF("hello");jclass clazz=env->FindClass("com/xxx/Foo");jstring str=env->NewStringUTF("hello");jobject obj=env->CallObjectMethod(thiz,methodId);}

这里面的str、clazz、str、obj甚至thiz、env都是LocalRef
它的生命周期是:当前 native 方法调用期间有效。native 方法返回后,LocalRef 通常会被 JVM 自动释放。

LocalRef 的两个典型错误

错误 1:把 LocalRef 保存到全局变量

staticjobject gCallback=nullptr;extern"C"JNIEXPORTvoidJNICALLJava_com_xxx_NativeBridge_nativeInit(JNIEnv*env,jobject thiz,jobject callback){gCallback=callback;// 错}

callback 是 LocalRef。
nativeInit 返回后,这个引用可能失效。
后面再用 gCallback 回调 Java,可能触发 JNI DETECTED ERROR,甚至 SIGABRT。
正确做法是

gCallback=env->NewGlobalRef(callback);

错误 2:循环里创建大量 LocalRef 不释放

for(inti=0;i<100000;i++){jstring str=env->NewStringUTF("hello");// 没有 DeleteLocalRef}

虽然 LocalRef 会在 native 方法返回时统一释放,但如果一个 native 方法内部循环创建太多 LocalRef,可能在返回前就把 local reference table 撑爆。
最好是env->DeleteLocalRef(str);手动释放一下

Global Reference:全局引用

如果 native 层要长期保存 Java 对象,就必须用 GlobalRef。
上已经展示过写法了
GlobalRef 的特点:

  1. 可以跨 native 方法调用保存。
  2. 可以跨线程使用。
  3. 会阻止 Java 对象被 GC。
  4. 必须手动 DeleteGlobalRef。

重点是第 3 点。如果你一直不释放,那么这个 Java callback 对象就一直被 native 持有,GC 不会回收它。如果 callback 持有 Activity,就可能造成 Activity 泄漏。

Weak Global Reference:弱全局引用

WeakGlobalRef 是弱引用版本的 GlobalRef。
创建方式:

jweak gWeakCallback=env->NewWeakGlobalRef(callback);

它的特点是:

  1. 可以跨调用、跨线程保存。
  2. 不阻止 Java 对象被 GC。
  3. 使用前必须判断对象是否还活着。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/1 2:38:35

OpenHarness源码研究-6-架构全景与设计模式总结

OpenHarness源码研究-6-架构全景与设计模式总结 前言 把前5篇的东西串起来&#xff0c;看整个项目靠什么设计模式撑起来的 完整数据流 一次 oh -p "帮我改个bug" 从头到尾经过的路径&#xff1a; ┌────────────────────────────────…

作者头像 李华
网站建设 2026/7/1 2:36:20

四川大学《微积分I-1》期末试卷及答案2016-2025学年PDF

四川大学《微积分I-1》期末试卷及答案2016-2025学年PDF 包括&#xff1a; 四川大学《微积分(I&#xff09;-1》2016-2017学年第一学期期末试卷.pdf 四川大学《微积分&#xff08;I&#xff09;-1》2017-2018学年第一学期期末试卷及答案.pdf 四川大学《微积分&#xff08;I&…

作者头像 李华
网站建设 2026/7/1 2:35:17

问题求解策略期末复习

“廉颇老矣&#xff0c;尚能饭否&#xff1f;”&#xff0c;事隔两个月&#xff0c;为了备战期末重出江湖啦&#xff01;和我一起一晚上速成C吧~问题 A: 区间素数个数统计题目描述给定两个整数 L 和 R&#xff08;1 ≤ L ≤ R ≤ 10000&#xff09;&#xff0c;请你统计区间 [L…

作者头像 李华
网站建设 2026/7/1 2:34:00

Java毕设选题推荐:基于 SpringBoot 的校园外卖骑手调度管理系统的设计与实现 基于 SpringBoot 的高校餐饮线上订购配送系统【附源码、mysql、文档、调试+代码讲解+全bao等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/7/1 2:33:21

Shizuku:不 Root 也能调系统 API

文章目录Shizuku&#xff1a;不 Root 也能调系统 API1、它在解决什么问题2、开发者怎么接入3、需要注意的几个点4、适合什么场景Shizuku&#xff1a;不 Root 也能调系统 API Shizuku 在 GitHub 上拿到了 26,807 Star。 这个工具解决了一个 Android 开发里的老问题&#xff1a…

作者头像 李华
网站建设 2026/7/1 2:33:03

LeWorldModel:1GB显存跑通JEPA世界模型,AI预测学习从入门到实践

上周在 GitHub 上看到一个项目&#xff0c;叫 LeWorldModel&#xff0c;短短几天就冲到了 4k star。点进去一看&#xff0c;介绍里写着“基于 JEPA 框架的世界动作模型&#xff0c;1GB 显存可运行”。说实话&#xff0c;看到“世界模型”和“1GB 显存”这两个词放在一起&#x…

作者头像 李华