外部函数与内存API(FFM)- ERR404博客
随着JDK 22和JEP 424的发布,Java引入了一个全新的特性:外部函数与内存API(Foreign Function and Memory API,简称 FFM)。本文将详细介绍该API的设计初衷、核心组件以及使用方法,帮助开发者更好地理解和应用这一技术。
外部函数与内存API的设计初衷
Java平台提供了丰富的工具、库和驱动(如JDBC、HTTP、NIO、套接字等),但在某些场景下,开发者仍需与JVM之外的资源进行交互。FFM API的诞生正是为了解决这一问题,它通过高效调用外部函数和安全访问外部内存,使Java程序能够与原生库和数据进行互操作,同时避免了JNI(Java Native Interface)的复杂性和潜在风险。
FFM API主要位于java.base模块的java.lang.foreign包中。通过该API,开发者可以分配、访问和管理外部内存,从而实现与JVM外部资源的通信。
核心组件概览
FFM API的核心组件包括以下几个部分:
- MemorySegment:表示一段连续的内存区域。
- MemoryAddress:提供指向内存段中特定位置的指针。
- SegmentAllocator:用于分配具有特定特征(如大小和对齐方式)的内存段。
- Linker、FunctionDescriptor 和 SymbolLookup:用于调用外部函数。
这些组件共同构成了FFM API的基础,开发者可以利用它们高效、安全地操作外部内存和调用外部函数。
使用指南
链接器(Linker)
链接器是实现Java程序与JVM外部通信的核心组件。开发者通常使用针对操作系统和处理器架构优化的nativeLinker()方法,以确保与原生库和函数交互时的兼容性和效率。如果项目有特殊需求,也可以选择第三方原生链接器,但需综合考虑以下因素:
- 平台兼容性
- 性能
- 易用性
- 社区支持
- 可靠性
从原生库查找符号
符号是指需要从Java代码访问的外部库中定义的函数或变量。实现步骤如下:
- 获取一个或多个库中符号的地址。
- 通过
FunctionDescriptor接口指定待调用函数的签名和调用约定,包括参数类型、返回类型等特征。 - 获取符号地址并定义描述符后,使用
MethodHandles API将其转换为MethodHandle。
以下是一个示例:将接收两个整数参数并返回double类型的函数转换为MethodHandle,以便在Java代码中调用。
// 定义参数类型和返回类型
FunctionDescriptor descriptor = FunctionDescriptor.of(CLinker.C_DOUBLE, CLinker.C_INT, CLinker.C_INT);
MethodHandle handle = linker.downcallHandle(symbol, descriptor);
分配内存区域
在与需要手动内存管理的外部库交互时,FFM允许开发者在Java堆外分配和管理内存。这种方式确保底层函数能够读取参数,因为Java运行时中可能不存在必要的内存空间。
需要注意的是,实际开发中存储的通常是数据指针而非数据本身。例如,在处理链表等复杂数据结构时,开发者需要逐个分配列表项的内存,这可能会显得繁琐。
调用外部函数
通过包含参数的内存区域调用外部函数。借助MethodHandle,开发者可以轻松实现函数调用。例如,假设外部库中定义了一个接收两个整数参数并返回double的函数myFunction,可以通过以下方式调用:
double result = (double) handle.invokeExact(10, 20);
读取堆内存区域结果
对于像radixsort这样直接修改输入数据且无返回值的函数,需要在同一内存区域重新读取数据。以下是一个示例:
MemorySegment segment = MemorySegment.allocateNative(100);
radixsort(segment);
byte[] result = segment.toArray(ValueLayout.JAVA_BYTE);
FFM API的优势
FFM相比传统的JNI具有以下显著优势:
- 模板代码更少:减少了重复性代码的编写。
- API更简洁:提高了代码的可读性和维护性。
- 内存管理更轻量:开发者可以更高效地管理堆外内存。
- 类型安全:避免了JNI中常见的类型转换错误。
实际应用与反馈
目前,FFM API已在多个项目中得到了测试和应用。例如,RocksDB团队在测试FFM时发现,它在性能提升、代码精简和互操作性增强方面表现突出,为增强RocksDB的Java API及开拓新机遇提供了可靠的技术支持。
更多关于RocksDB团队的测试反馈,请参考:RocksDB博客。
总结
外部函数与内存API(FFM)为Java开发者提供了一个高效、安全的工具,用于与JVM外部资源进行交互。通过FFM,开发者可以更轻松地调用原生库、管理外部内存,并避免JNI的复杂性和风险。
希望本文对您了解FFM及其应用有所帮助。如有任何问题或建议,欢迎交流!更多关于JRE和内存区域的深入探讨,敬请期待后续内容。
原文链接: https://sebastienallemand.fr/posts/jep424-ffm/
热门API
- 1. AI文本生成
- 2. AI图片生成_文生图
- 3. AI图片生成_图生图
- 4. AI图像编辑
- 5. AI视频生成_文生视频
- 6. AI视频生成_图生视频
- 7. AI语音合成_文生语音
- 8. AI文本生成(中国)
最新文章
- 如何保护您的API免受自动化机器人和攻击 | Zuplo博客
- ASP.NET Core Minimal APIs 入门指南 – JetBrains 博客
- 什么是 OpenReview
- Vue中使用echarts@4.x中国地图及AMap相关API的使用
- 使用 Zeplin API 实现 Zeplin 移动化
- Rest API 教程 – 完整的初学者指南
- API Key 密钥 vs OAuth 2.0:身份认证的比较
- Claude API 能使用 OpenAI 接口协议吗?
- 使用DeepSeek R1、LangChain和Ollama构建端到端生成式人工智能应用
- 如何获取通义千问 API Key 密钥(分步指南)
- 您需要了解的OpenAI Assistants API功能 – PageOn.ai
- DRF库详解:用Django轻松搭建功能强大的API服务