Java 21 外部函数与内存 (FFM) API 简介

作者:API传播员 · 2025-10-31 · 阅读时间:5分钟
Java 21 外部函数与内存 (FFM) API 是 Java 21 引入的新功能,允许 Java 程序与外部代码和数据互操作,提供比 JNI 更安全、高效的解决方案,适用于调用本机函数和硬件交互等场景。

Java 21 外部函数与内存 (FFM) API 简介

Java 21 引入了外部函数和内存(FFM)API,这是一项全新的功能,允许 Java 程序与 Java 运行时之外的代码和数据进行互操作。Java 通常运行在被称为 Java 虚拟机(JVM)的托管环境中,JVM 作为执行 Java 代码与底层硬件和操作系统之间的抽象层。JVM 的核心设计原则之一是为 Java 应用程序提供一个安全且隔离的运行环境。这种隔离带来了诸多优势,例如增强安全性和稳定性,降低了未经授权访问系统资源或内存损坏的风险,从而避免了缓冲区溢出等漏洞。


为什么需要 FFM API?

尽管 JVM 的隔离特性提供了许多好处,但当 Java 应用程序需要与其他编程语言编写的系统级资源或库交互时,这种隔离可能会成为一种限制。例如:

  • 性能需求:某些性能关键的应用程序可能需要调用用 C 或 C++ 编写的本机库,以充分利用其速度优势。
  • 硬件交互:某些应用场景需要直接与硬件设备通信,而这通常需要通过本机库实现。

在过去,Java 程序通常通过 Java 本机接口(JNI)来完成这些任务。尽管 JNI 功能强大,但它也存在复杂性和潜在风险,例如内存泄漏和崩溃,这可能会破坏 Java 应用程序的稳定性。


FFM API 的优势

Java 21 引入的 FFM API 为解决上述问题提供了一种更安全、更高效的解决方案。与 JNI 不同,FFM API 通过简化的方式实现了对本机库的调用和本机数据的操作。它的设计目标是提供一种直接且安全的方式来实现 Java 与外部代码和数据的互操作,同时保留 JVM 隔离环境的安全性和稳定性。

以下是 FFM API 的主要优势:

  • 简化代码:减少了 JNI 中常见的样板代码,降低了出错的可能性。
  • 增强安全性:通过更安全的内存管理机制,降低了内存泄漏和崩溃的风险。
  • 提高效率:提供了更高效的方式来调用本机函数和操作本机数据。

使用示例:调用 C 的 strlen 函数

以下代码展示了如何使用 FFM API 调用 C 的 strlen 函数来计算传递的 Java 字符串的长度:

public static void main(String[] args) throws Throwable {
    // 创建一个 SymbolLookup 对象,用于在 C 库路径中查找本机符号
    SymbolLookup stdlib = Linker.nativeLinker().defaultLookup();

    // 创建一个 MethodHandle 对象,包含调用本机函数所需的信息
    MethodHandle strlen = Linker.nativeLinker().downcallHandle(
        stdlib.find("strlen").orElseThrow(),
        FunctionDescriptor.of(JAVA_LONG, ADDRESS)
    );    // 创建一个 Arena 对象,用于分配堆外内存
    try (Arena offHeap = Arena.ofConfined()) {
        // 分配堆外内存来存储字符串
        MemorySegment str = offHeap.allocateUtf8String("Java 21 rocks!");        // 调用 strlen 函数计算字符串长度
        long len = (long) strlen.invoke(str);
        System.out.println("len = " + len);
    }
}

示例解析

  1. 加载本机库:通过 SymbolLookup 对象查找本机符号。
  2. 获取函数指针:使用 MethodHandle 对象封装本机函数的调用信息。
  3. 分配内存:通过 Arena 对象分配堆外内存。
  4. 调用本机函数:调用 strlen 函数并获取结果。

以上代码展示了如何加载本机库、获取函数指针、分配内存、设置函数参数、调用本机函数并获取结果。


FFM API 的其他功能

FFM API 不仅支持简单的函数调用,还提供了许多其他功能,例如:

  • 支持复杂参数类型:可以调用带有字符串、数组等复杂参数类型的外部函数。
  • 高效内存管理:通过 Arena 提供安全的堆外内存分配和释放机制。

适用场景

FFM API 是 JNI 的一个安全、高效且易于使用的替代方案,适用于以下场景:

  1. 调用本机函数:当需要访问仅在本机库中可用的功能时,FFM API 提供了一种安全有效的调用方式。
  2. 与本机代码交互:例如,访问用 C 或 C++ 编写的机器学习库。
  3. 硬件交互:开发需要直接与硬件设备通信的应用程序。

如果您正在编写一个需要与本机代码交互的 Java 程序,FFM API 是一个理想的选择。它提供了一种安全、高效且可移植的方式来调用本机函数和访问本机数据。


总结

Java 21 的 FFM API 为 Java 程序与外部代码和数据的互操作提供了一个强大的工具。通过简化代码、增强安全性和提高效率,FFM API 成为 JNI 的理想替代方案。无论是调用本机函数、访问本机库,还是与硬件设备交互,FFM API 都能为开发者提供一种安全、高效且易于使用的解决方案。

原文链接: https://blog.payara.fish/java-21-foreign-function-and-memory-api