当前位置: 首页 > ai >正文

Android 如何理解 Java JNI 中的引用与 Java 对象的区别

在 Java JNI 中,"引用"和 Java 中的"对象引用"是不同维度的概念,主要体现在以下方面:​​

1. 本质与作用域​​

  • ​​Java 对象引用​​
    是 Java 语言层面的概念,指向堆内存中的对象实例。其生命周期由 JVM 自动管理,受垃圾回收(GC)机制控制。例如:
Object obj = new Object(); // Java 对象引用

这类引用会随着作用域结束或显式置为 null 而失效,GC 会自动回收未被引用的对象。

  • ​​​​JNI 引用​​
    是 JNI 层(C/C++ 代码)对 Java 对象的间接访问机制,本质是本地代码与 JVM 对象之间的桥梁。分为三种类型:
    • ​​​​局部引用(Local Reference)​​:仅在当前 JNI 方法或线程内有效,方法返回后自动释放。
    • ​​​​全局引用(Global Reference)​​:需手动创建(NewGlobalRef)和释放(DeleteGlobalRef),跨线程、跨方法有效,阻止 GC 回收对象。
    • ​​​​弱全局引用(Weak Global Reference)​​:类似全局引用,但不阻止 GC 回收对象。

2. 生命周期管理​​

  • ​​​​Java 对象引用​​
    由 JVM 自动管理。当对象不可达时(如引用被置为 null 或超出作用域),GC 会回收其内存。
  • ​​​​JNI 引用​​
    需开发者显式管理:
    • 局部引用若不及时释放(如循环中大量创建),可能导致 ​​JNI 引用表溢出​​(Reference Table Overflow)。
    • 全局引用需手动释放,否则会导致内存泄漏。
    • 弱全局引用需通过 IsSameObject 检查对象是否存活。

3. 引用初始化的时机​​

​​问题核心​​:为什么 JNI 引用可以在对象创建前被初始化?​​

  • JNI 引用指向的是元数据,而非对象实例​​
    JNI 中的 jclass(类引用)或 jmethodID(方法 ID)等,本质是 ​​元数据引用​​,与 Java 类的加载机制相关:
    • 当 JVM 加载类时(如通过 FindClass),会生成类的元数据(如方法表、字段表),此时 jclass 已可被初始化,无需实例化对象。
    • 例如,通过 FindClass(“java/lang/String”) 获取 jclass 时,即使未创建 String 对象,也能获取该类的元数据。
  • ​​Java 对象引用必须指向已存在的实例​​
    Java 中的 new 操作会触发对象实例化,引用必须在对象创建后才能绑定。例如:
String s; // 声明引用(未初始化)
s = new String(); // 对象创建后引用才有效

4. 典型场景对比​​

​​5. 引用的设计意义​​

  • 性能优化​​
    JNI 允许预先缓存 jclass 或 jmethodID(如全局引用),避免重复查找元数据,提升跨层调用效率。
  • 跨语言交互​​
    通过引用机制,本地代码可安全访问 JVM 对象,避免直接操作内存导致的野指针问题。
  • 生命周期解耦​​
    JNI 引用(尤其是弱全局引用)允许本地代码感知 Java 对象的生命周期,但不会强制保持对象存活。

总结

Java JNI 中的引用是 ​​本地代码与 JVM 对象交互的句柄​​,其本质是对元数据或对象访问权限的封装,允许在对象实例化前初始化(如类元数据);而 Java 中的对象引用是 ​​直接指向堆内存的实例指针​​,必须在对象创建后生效。理解两者的区别,有助于避免 JNI 开发中的内存泄漏和性能问题。

http://www.xdnf.cn/news/4351.html

相关文章:

  • Kafka Controller的作用是什么?故障时如何恢复? (管理分区和副本状态;通过ZooKeeper选举新Controller)
  • Linux系统Shell脚本之shell函数
  • Kafka的核心组件有哪些?简要说明其作用。 (Producer、Consumer、Broker、Topic、Partition、ZooKeeper)
  • java多线程------synchronized
  • CVE体系若消亡将如何影响网络安全防御格局
  • git合并分支后回滚,再次合并导致更改没有合并的问题
  • CentOS 7 基础环境安装脚本
  • Milvus(16):索引解释
  • 【前端基础】6、CSS的文本属性(text相关)
  • 嵌入式通信协议总览篇:万物互联的基石
  • 记一次SSE数据被缓存导致实时性失效问题
  • 链表——C语言
  • 常见的卷积神经网络列举
  • 用go从零构建写一个RPC(仿gRPC,tRPC)--- 版本1(Client端)
  • Umi+React+Xrender+Hsf项目开发总结
  • 基于Django汽车数据分析大屏可视化系统项目
  • SSHv2 密钥交换(Key Exchange)详解
  • 体育培训的实验室管理痛点 质检LIMS如何重构体育检测价值链
  • TikTok 矩阵运营新手实操保姆级教程 2.0 版本
  • 从一次被抄袭经历谈起:iOS App 安全保护实战
  • 【AWS+Wordpress-准备阶段】AWS注册+创建EC2实例
  • Scrapy框架之Scrapyd部署及Gerapy分布式爬虫管理框架的使用
  • 记录学习《手动学习深度学习》这本书的笔记(十)
  • 协方差与皮尔逊相关系数:从定义到应用的全面解析
  • isNotBlank和isNotEmpty有什么区别?
  • Python学习笔记--FastAPI入门常规操作
  • penEuler操作系统结合豆包测试github仓库8086-Emulator项目
  • react中的用法——setDisabled dva dispatch effects
  • leetcode 160. 相交链表
  • os梳理5——第五章:存储器管理