The Foreign-Memory Access API provides a way to access native memory safely and efficiently, useful for interop with native libraries. This is an incubator feature introduced in Java 14.
NOTE: This is an incubator feature and requires:
--add-modules jdk.incubator.foreign--enable-preview
WARNING: This API may change in future versions as it's still incubating.
# Compile
javac --enable-preview \
--add-modules jdk.incubator.foreign \
--release 14 \
ForeignMemoryAccessAPI.java
# Run
java --enable-preview \
--add-modules jdk.incubator.foreign \
ForeignMemoryAccessAPIRepresents a contiguous region of memory. Can be allocated from native memory or mapped from a file.
Provides type-safe access to memory segments. Includes methods for reading and writing different data types.
Describes memory layouts for structured data. Useful for working with C structs or other structured memory formats.
Represents a memory address. Used for pointer-like operations.
import jdk.incubator.foreign.*;
// Allocate native memory
try (MemorySegment segment = MemorySegment.allocateNative(100)) {
// Write to memory
MemoryAccess.setIntAtOffset(segment, 0, 42);
MemoryAccess.setIntAtOffset(segment, 4, 100);
// Read from memory
int value1 = MemoryAccess.getIntAtOffset(segment, 0);
int value2 = MemoryAccess.getIntAtOffset(segment, 4);
System.out.println("Value 1: " + value1); // 42
System.out.println("Value 2: " + value2); // 100
}
// Memory is automatically freed when segment is closed- Safe Memory Access: Bounds checking prevents memory errors
- Automatic Resource Management: Memory is automatically freed using try-with-resources
- Type-Safe Operations: Prevents type errors at compile time
- Better than JNI: Easier to use than Java Native Interface for many use cases
- Useful for Native Library Interop: Simplifies interaction with native libraries
-
Interfacing with Native Libraries
- Call native functions that require memory buffers
- Pass data structures to native code
- Receive data from native code
-
High-Performance Memory Operations
- Direct memory access for performance-critical code
- Zero-copy operations
- Efficient data processing
-
System-Level Programming
- Direct hardware access
- Operating system APIs
- Device drivers
-
Zero-Copy Operations
- Avoid copying data between Java and native code
- Efficient data transfer
- Reduced memory overhead
-
Direct Memory Access for Performance
- Bypass Java heap for performance
- Lower latency operations
- Better cache locality
import jdk.incubator.foreign.*;
public class MemoryExample {
public static void main(String[] args) {
// Allocate 100 bytes of native memory
try (MemorySegment segment = MemorySegment.allocateNative(100)) {
// Write different types to memory
MemoryAccess.setIntAtOffset(segment, 0, 42);
MemoryAccess.setLongAtOffset(segment, 4, 123456789L);
MemoryAccess.setDoubleAtOffset(segment, 12, 3.14159);
// Read back
int intValue = MemoryAccess.getIntAtOffset(segment, 0);
long longValue = MemoryAccess.getIntAtOffset(segment, 4);
double doubleValue = MemoryAccess.getDoubleAtOffset(segment, 12);
System.out.println("Int: " + intValue);
System.out.println("Long: " + longValue);
System.out.println("Double: " + doubleValue);
}
// Memory automatically freed here
}
}- Incubator Feature: This API is still incubating and may change in future Java versions
- Module Requirements: Requires
--add-modules jdk.incubator.foreign - Preview Feature: Requires
--enable-previewflag - Automatic Memory Management: Memory is automatically managed using try-with-resources
- Bounds Checking: Prevents memory errors through bounds checking
- Type Safety: Type-safe operations prevent type errors
This API is being refined as part of Project Panama, which aims to improve interop with native code. The API may become a standard feature in future Java versions.
- Simplify native code interop
- Improve performance
- Better safety guarantees
- Easier to use than JNI
// Requires native code
// Complex setup
// Manual memory management
// Error-prone// Pure Java (with incubator modules)
// Simpler setup
// Automatic memory management
// Type-safe and bounds-checked- Easier to Use: No need to write native code
- Type Safe: Compile-time type checking
- Memory Safe: Automatic bounds checking
- Resource Management: Automatic cleanup with try-with-resources
- Better Performance: Optimized for modern JVMs
- Still incubating (API may change)
- Requires preview and module flags
- Not all use cases are covered yet
- Some features may be missing compared to JNI
- JEP 370: Foreign-Memory Access API (Incubator)
- Project Panama
- Java API Documentation for
jdk.incubator.foreignpackage
The Foreign-Memory Access API provides a modern, safe, and efficient way to access native memory from Java. While still incubating, it represents a significant improvement over traditional JNI for many use cases. It's particularly useful for applications that need to interface with native libraries or require high-performance memory operations.