The Foreign Memory Access API is designed to replace the Unsafe and ByteBuffer APIs, addressing their limitations such as size constraints and limited access modes. It supports long offsets, enabling larger memory segments, and includes advanced access modes like volatile and compare-and-swap. It also introduces deterministic memory allocation, allowing developers to explicitly free memory when needed.
The Foreign Function API eliminates the need for an intermediate glue code layer written in C or C++. Instead, the entire intermediate layer can be written in pure Java, simplifying the process and reducing the need for additional build pipelines or learning new languages. This also improves performance due to better visibility and optimization by the JIT compiler.
The API went through several iterations, with significant redesigns of the programming model, particularly around lifetime management of memory resources. The introduction of 'arenas' allows for safer and more deterministic memory management. Additionally, support for more function shapes and platforms was added, and a fallback implementation based on libffi was introduced.
The API benefits from the 'Panama effect,' where the JIT compiler can optimize the glue code written in Java more effectively than the intermediate C/C++ code used in JNI. Additionally, upcalls (native code calling back into Java) are up to three times faster due to the efficient handling of method handles and machine code stubs.
Libraries like Lucene, Netty, and Tomcat have adopted the API, primarily to replace their usage of Unsafe. These libraries have observed performance parity with Unsafe while gaining safer memory management through the API's lifetime management features.
Developers can use the Jextract tool, which parses a native library's header file and automatically generates Java wrapper functions. This allows developers to call native library functions directly from Java without writing any C/C++ code.
The API is finalized in JDK 22 and no longer requires the --enable-preview flag. Future work includes improving the Jextract tool to generate more self-contained and editable code snippets for easier integration with Java projects.
The Foreign Function and Memory API will be finalised in JDK 22. This API helps you integrate native code within your Java program.
Using this new API you can efficiently invoke code outside the JVM, safely access memory not managed by the JVM, call native libraries and process native data without the brittleness and danger of JNI.
Jorn Vernee, core contributor and maintainer of the FFM API, is Ana’s guest during this episode. Jorn explains what is the Foreign Memory Access API, its goals and the iterations that this API went through. Jorn also shares a few examples of Java libraries that already adopted the FFM API, the performance improvements they observed. He also explains how you can use this new API to integrate a native library within your own Java code.