-
CSR
-
Resolution: Approved
-
P3
-
low
-
Java API
-
JDK
Summary
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.
Problem
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.
Solution
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).
Specification
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
A 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).
A 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
jdk.incubator.foreign
module tojava.base
- rename the
jdk.incubator.foreign
package tojava.foreign
- move the combinators/factories in
MemoryHandles
intojava.lang.invoke.MethodHandles
- move some of the constants in
MemoryLayouts
(such asJAVA_INT
,JAVA_FLOAT
and so forth) into the corresponding primitive wrapper class (e.g.MemoryLayouts::JAVA_INT
will becomeInteger::LAYOUT
)
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
- csr of
-
JDK-8234049 Implementation of Memory Access API (Incubator)
-
- Resolved
-
- relates to
-
JDK-8235836 Cleanup memory access API javadoc
-
- Closed
-
-
JDK-8236769 Clarify javadoc of memory access API
-
- Closed
-
-
JDK-8236853 Memory access API refinements
-
- Closed
-
-
JDK-8243496 Implementation of Foreign-Memory Access API (Second Incubator)
-
- Closed
-