外部函数与内存API:弥合Java与原生库之间的鸿沟

JEP 454: Foreign Function & Memory API 集成至 JDK 22

主要观点

JEP 454(Foreign Function & Memory API)已从“Targeted”状态提升为“Integrated”状态,并计划在 JDK 22 中正式发布。该 API 旨在改进 Java 与本地代码的交互,提供更高效、更安全的方式来访问本地库和管理本地内存。

关键信息

  1. 发展历程

    • JEP 412(JDK 17):首次孵化。
    • JEP 419(JDK 18):第二次孵化。
    • JEP 424(JDK 19):首次预览。
    • JEP 434(JDK 20):第二次预览。
    • JEP 442(JDK 21):第三次预览。
    • JEP 454(JDK 22):正式集成。
  2. 改进内容

    • 新增 Enable-Native-Access 清单属性,允许可执行 JAR 文件中的代码在不使用 --enable-native-access 标志的情况下调用受限方法。
    • 支持客户端构建 C 函数描述符,避免使用平台特定的常量。
    • 改进了对本地内存中可变长度数组的支持。
    • 支持本地字符串中的多种字符集。
  3. API 组成部分

    • Foreign Function Interface (FFI):允许 Java 程序调用 C 和 C++ 等本地语言编写的函数,减少与 Java Native Interface (JNI) 相关的样板代码。
    • Memory Access API:提供与本地内存交互的工具,包括内存分配、释放和操作本地数据结构的功能,并提供安全检查以防止缓冲区溢出等常见问题。
  4. 核心类

    • Linker:链接 Java 代码与符合特定应用二进制接口 (ABI) 的库中的外部函数。
    • SymbolLookup:用于检索库中符号(如函数或全局变量)的地址。
    • MemorySegment:提供对连续内存区域的访问,支持堆内和堆外内存。
    • MethodHandle:表示对底层方法、构造函数或字段的强类型、可直接执行的引用。
    • FunctionDescriptor:建模外部函数的签名,用于创建下调用方法句柄和上调用存根。
    • Arena:控制本地内存段的生命周期,提供分配和释放方法。
  5. 示例代码

    • 展示了如何使用 FFM API 调用 C 库中的 radixsort 函数对字符串数组进行排序。
  6. 与传统方法的对比

    • 传统的 Java 开发人员使用 ByteBuffer 对象进行堆外内存操作,而 FFM API 引入了 MemorySegment 对象,提供更精细的控制。
    • FFM API 与 java.nio.channels API 对齐,提供了确定性的堆外字节缓冲区释放方法,避免了非标准技术的使用。

重要细节

  • 安全性:FFM API 提供了安全检查,防止缓冲区溢出等常见问题。
  • 互操作性:API 提供了更无缝、符合 Java 习惯的方式来与本地库交互,是 JNI 的替代方案。
  • 开发体验:简化了 Java 与本地代码的交互,减少了复杂性和潜在的安全问题。

结论

FFM API 的集成标志着 Java 平台在安全性和效率方面的进一步提升。它为开发人员提供了更简单、更安全的工具来处理 Java 与本地代码的交互,有望彻底改变 Java 与本地库的交互方式。

阅读 31
0 条评论