Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8234050

Implementation of Memory Access API (Incubator)



    • low
    • Java API
    • JDK



      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

      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 to java.base
      • rename the jdk.incubator.foreign package to java.foreign
      • move the combinators/factories in MemoryHandles into java.lang.invoke.MethodHandles
      • move some of the constants in MemoryLayouts (such as JAVA_INT, JAVA_FLOAT and so forth) into the corresponding primitive wrapper class (e.g. MemoryLayouts::JAVA_INT will become Integer::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


        Issue Links



              mcimadamore Maurizio Cimadamore
              mcimadamore Maurizio Cimadamore
              Alan Bateman, Paul Sandoz
              0 Vote for this issue
              4 Start watching this issue