Provide an incubator module, jdk.incubator.foreign, which contains an API, referred to as the Memory Access API, that is designed to facilitate safe and structured access to off-heap and on-heap memory. This API provides the fundamental building blocks to replace JNI.
To date, there is no optimal solution for accessing off-heap memory. While access to off-heap memory is possible using the ByteBuffer API, such an API has certain limitations (stateful-ness, addressing space bound by the 2G limit, non-deterministic deallocation, structural access) which makes it unsuitable as a general off-heap API, especially when it comes to interoperating with native code. Other alternatives are available, such as Unsafe (efficient, but not supported) or JNI (supported but inefficient), but ultimately no ideal solution and/or API exists.
The memory access API addresses the aforementioned problems by providing a memory access API that is general (can be used both for off-heap and on-heap access), safe (uses of this API cannot cause any hard JVM crash) and efficient (this is achieved by making immutability and deterministic-deallocation two central design choices of the API). Such an API lends itself well to all cases where e.g. the ByteBuffer API is currently used to access off-heap memory; since this new API doesn't incur in the 2G addressing space limit, it is particularly apt to model persistent memory (see https://openjdk.java.net/jeps/352). In addition, since this API separates memory segment descriptions from the way in which such segments are accessed, it also lends well to use cases where the same memory segment needs to be shared across multiple views or slices (a common use case in tensor programming, or access to multi-dimensional arrays of values).
The implementation of the memory access API exports the following interfaces in the package jdk.incubator.foreign, defined in module jdk.incubator.foreign:
MemorySegment Models a contiguous region of memory MemoryAddress Models an offset within a memory segment MemoryLayout Models (optional) descriptions of the contents of a memory segment MemoryLayout.PathElement Constructs layout paths which can be helpful to retrieve offset to a specific layout element
MemorySegment is a static and immutable description of a region of memory. A
MemorySegment is always associated with spatial bounds (e.g. the minimum and maximum address within the segment) as well as temporal bounds (which define when it is safe to access the segment). To support deterministic-deallocaton, memory segments support the
AutoCloseable interface, so that they can be closed when no longer in use (closing a memory segment might trigger deallocation of the memory resources, if any, associated with the segment).
MemoryLayout is a programmatic description of a memory segment contents. The
MemoryLayout interface provide ways to mechanically derive information from layouts, using so called layout paths - that is, given a toplevel layout, and a path (expressed as a list of
PathElement instances), it is possible to derive information such as the offset of the selected layout elements within the toplevel layout; or the
VarHandle accessor required to access the selected layout elements given a
MemoryAddress instance which points to a memory segment with the toplevel layout.
Additionally, the implementation of the memory access API will export the following classes:
GroupLayout Models compound layouts (e.g. structs or unions) SequenceLayout Models array layouts. ValueLayout Models value layouts - e.g. sequence of bits MemoryHandles Defines several factory methods for constructing and combining memory access var handles MemoryLayouts Defines useful (and common) layout constants.
The first three classes are specific subclasses implementing the
MemoryLayout interface. Each of those classes provide access to specific properties; for instance a
SequenceLayout has an (optional) element count, and a sequence element layout. The
MemoryHandles class defines several factories and combinators for the
VarHandle instances which can be used to access memory segments. Similarly, the
MemoryLayouts class contains several layout constants that can be useful to developers.
When the memory access API exits the incubating stage, we plan to make at least the following adjustments:
- move the functionality from the
- rename the
- move the combinators/factories in
- move some of the constants in
JAVA_FLOATand so forth) into the corresponding primitive wrapper class (e.g.
The javadoc for the package with the implementation (updated live) is available at http://cr.openjdk.java.net/~mcimadamore/panama/memaccess_javadoc ; a copy (as of December 9, 2019) is also attached here.
More details can be found in the JEP issue - https://bugs.openjdk.java.net/browse/JDK-8227446