Details

    • Type: CSR
    • Status: Closed
    • Priority: P4
    • Resolution: Approved
    • Fix Version/s: 14
    • Component/s: core-libs
    • Labels:
      None
    • Compatibility Kind:
      behavioral
    • Compatibility Risk:
      minimal
    • Compatibility Risk Description:
      The new implementation will not change behaviour or APIs for existing clients. It only introduces new behaviour for clients that explicitly employ the newly exposed MapMode values.
    • Interface Kind:
      Java API
    • Scope:
      JDK

      Description

      Summary

      Enhance class java.nio.MappedByteBuffer so that instances can be mapped via a file belonging to a file system mounted from an non-volatile memory (NVM) device, allowing writes to be committed via an efficient cache-line flush.

      Problem

      NVM offers the opportunity for application programmers to create and update program state across program runs without incurring the significant copying and/or translation costs that output to and input from a persistent medium normally implies. This is particularly significant for transactional programs, where regular persistence of in-doubt state is required to enable crash recovery.

      Existing C libraries (such as Intel's libpmem) provide C programs with highly efficient access to NVM at the base level. They also build on this to support simple management of a variety of persistent data types. Currently, use of even just the base library from Java is costly because of the frequent need to make system calls or JNI calls to invoke the primitive operation which ensures memory changes are persistent. The same problem limits use of the higher-level libraries and is exacerbated by the fact that the persistent data types provided in C are allocated in memory not directly accessible from Java. This places Java applications and middleware (for example, a Java transaction manager) at a severe disadvantage compared with C or languages which can link into C libraries at low cost.

      This proposal attempts to remedy the first problem by allowing efficient writeback of NVM mapped to a ByteBuffer. Since ByteBuffer-mapped memory is directly accessible to Java this proposal enables the second problem to be addressed by implementing client libraries equivalent to those provided in C to manage storage of different persistent data types.

      Solution

      A public extension enumeration ExtendedMapMode will be added to package jdk.nio.mapmode in a newly created module of the same name. Module jdk.nio.mapmode will export this package unconditonally. Enumeration ExtendedMapMode will expose two new MapMode enumeration values READ_ONLY_SYNC and READ_WRITE_SYNC.

      Method FileChannelImpl.map will be modified to recognize these modes and, when specified, return a MappedByteBuffer that has been mapped to NVM. The file channel for the mapping must belong to a file system which can be mapped to memory using the mmap flags MAP_SYNC and MAP_SHARED_VALIDATE.

      Methods force() and force(long,long) of MappedByteBuffer will be modified to respect the mapping of the mapped memory to NVM or volatile memory. In the former case writeback operations will proceed using a new internal API that flushes changes using cache line writeback. In the latter case the existing writeback implementation will be retained, employing file descriptor-based force operations.

      Statistics for mapped NVM buffers will be published via a new BufferPoolMXBean. Class ManagementFactory provides method List<T> getPlatformMXBeans(Class<T>) which can be used to retrieve a list of BufferPoolMXBean instances tracking count, total_capacity and memory_used for the existing categories of mapped or direct byte buffers. It will be modified to return an extra, new BufferPoolMXBean with name "mapped - 'non-volatile memory'", which will track the above stats for all MappedByteBuffer instances currently mapped with mode ExtendedMapMode.READ_ONLY_SYNC or ExtendedMapMode.READ_WRITE_SYNC. The existing BufferPoolMXBean with name mapped will continue only to track stats for MappedByteBuffer instances currently mapped with mode MapMode.READ_ONLY, MapMode.READ_WRITE or MapMode.PRIVATE.

      The new MapMode values and new implementation of FileChannelImpl.map do not imply a change to the API of the map operation. However, they do introduce new error cases. These are specified in the javadoc of ExtendedMapMode but a few extra comments are required:

      The new implementation of FileChannelImpl.map may only be implemented on specific platforms: initially this will be x86_64/Linux and AArch64/Linux. If the new MapMode values are passed to map on unsupported platforms an UnsupportedOperationException will be thrown.

      In the case of AArch64, UnsupportedOperationException will be thrown when the current CPU does not implement the hardware instructions needed to support cache line writeback to memory (all current ARMv8.1 CPUs and, potentially, some ARMv8.2 CPUs).

      The new implementation of FileChannelImpl.map may throw IOException, even on a supported platform. This will occur if the underlying OS implementation does not implement support for mapping into memory files from a file system associated with an NVM device. It will also happen if the file associated with the FileChannel does not belong to such a file system.

      Specification

      The new Map Modes are documented as follows:

      /**
       * Defines JDK-specific file mapping modes.
       *
       * @moduleGraph
       * @since 14
       */ 
      module jdk.nio.mapmode; {
          exports jdk.nio.mapmode;
      }
      
      package jdk.nio.mapmode;
      
      /**
       * JDK-specific file mapping modes.
       *
       * @since 14
       * @see java.nio.channels.FileChannel#map
       */
      public class ExtendedMapMode {
          private ExtendedMapMode() { }
      
          /**
           * File mapping mode for a read-only mapping of a file backed by
           * non-volatile RAM.
           *
           * <p> The {@linkplain FileChannel#map map} method throws
           * {@linkplain UnsupportedOperationException} when this map mode
           * is used on an implementation that does not support it.
           *
           * @implNote On Linux, the {@code MAP_SYNC} and {@code
           * MAP_SHARED_VALIDATE} flags are specified to {@code mmap} when
           * mapping the file into memory.
           */
          public static final MapMode READ_ONLY_SYNC = . . .
      
          /**
           * File mapping mode for a read-write mapping of a file backed by
           * non-volatile RAM. {@linkplain MappedByteBufefr#force force}
           * operations on a buffer created with this mode will be performed
           * using cache line writeback rather than proceeding via a file
           * device flush.
           *
           * <p> The {@linkplain FileChannel#map map} method throws
           * {@linkplain UnsupportedOperationException} when this map mode
           * is used on an implementation that does not support it.
           *
           * @implNote On Linux, the {@code MAP_SYNC} and {@code
           * MAP_SHARED_VALIDATE} flags are specified to {@code mmap} when
           * mapping the file into memory.
           */
          public static final MapMode READ_WRITE_SYNC = . . .
      }

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                adinn Andrew Dinn
                Reporter:
                adinn Andrew Dinn
                Reviewed By:
                Alan Bateman
              • Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: