MemorySegment (Java SE 15 & JDK 15)
Description: declaration: module: jdk.incubator.foreign, package: jdk.incubator.foreign, interface: MemorySegment
Keywords: jdk.incubator.foreign.MemorySegment interface

Module jdk.incubator.foreign
Package jdk.incubator.foreign

# Interface MemorySegment

All Superinterfaces:
  `AutoCloseable`

All Known Subinterfaces:
  `MappedMemorySegment`

    public interface MemorySegment
    extends AutoCloseable

A memory segment models a contiguous region of memory. A memory segment is associated with both spatial and temporal bounds. Spatial bounds ensure that memory access operations on a memory segment cannot affect a memory location which falls outside the boundaries of the memory segment being accessed. Temporal bounds ensure that memory access operations on a segment cannot occur after a memory segment has been closed (see `close()`).

All implementations of this interface must be value-based; use of identity-sensitive operations (including reference equality (`==`), identity hash code, or synchronization) on instances of `MemorySegment` may have unpredictable results and should be avoided. The `equals` method should be used for comparisons.

Non-platform classes should not implement MemorySegment directly.

## Constructing memory segments from different sources

There are multiple ways to obtain a memory segment. First, memory segments backed by off-heap memory can be allocated using one of the many factory methods provided (see `allocateNative(MemoryLayout)`, `allocateNative(long)` and `allocateNative(long, long)`). Memory segments obtained in this way are called native memory segments.

It is also possible to obtain a memory segment backed by an existing heap-allocated Java array, using one of the provided factory methods (e.g. `ofArray(int[])`). Memory segments obtained in this way are called array memory segments.

It is possible to obtain a memory segment backed by an existing Java byte buffer (see `ByteBuffer`), using the factory method `ofByteBuffer(ByteBuffer)`. Memory segments obtained in this way are called buffer memory segments. Note that buffer memory segments might be backed by native memory (as in the case of native memory segments) or heap memory (as in the case of array memory segments), depending on the characteristics of the byte buffer instance the segment is associated with. For instance, a buffer memory segment obtained from a byte buffer created with the `ByteBuffer.allocateDirect(int)` method will be backed by native memory.

Finally, it is also possible to obtain a memory segment backed by a memory-mapped file using the factory method `mapFromPath(Path, long, long, FileChannel.MapMode)`. Such memory segments are called mapped memory segments (see `MappedMemorySegment`).

Array and buffer segments are effectively views over existing memory regions which might outlive the lifecycle of the segments derived from them, and can even be manipulated directly (e.g. via array access, or direct use of the `ByteBuffer` API) by other clients. As a result, while sharing array or buffer segments is possible, it is strongly advised that clients wishing to do so take extra precautions to make sure that the underlying memory sources associated with such segments remain inaccessible, and that said memory sources are never aliased by more than one segment at a time - e.g. so as to prevent concurrent modifications of the contents of an array, or buffer segment.

## Closing a memory segment

Memory segments are closed explicitly (see `close()`). When a segment is closed, it is no longer alive (see `isAlive()`, and subsequent operation on the segment (or on any `MemoryAddress` instance derived from it) will fail with `IllegalStateException`.

Closing a segment might trigger the releasing of the underlying memory resources associated with said segment, depending on the kind of memory segment being considered:

- closing a native memory segment results in freeing the native memory associated with it
- closing a mapped memory segment results in the backing memory-mapped file to be unmapped
- closing a buffer, or a heap segment does not have any side-effect, other than marking the segment as not alive (see `isAlive()`). Also, since the buffer and heap segments might keep strong references to the original buffer or array instance, it is the responsibility of clients to ensure that these segments are discarded in a timely manner, so as not to prevent garbage collection to reclaim the underlying objects.

## Access modes

Memory segments supports zero or more access modes. Supported access modes are `READ`, `WRITE`, `CLOSE`, `ACQUIRE` and `HANDOFF`. The set of access modes supported by a segment alters the set of operations that are supported by that segment. For instance, attempting to call `close()` on a segment which does not support the `CLOSE` access mode will result in an exception.

The set of supported access modes can only be made stricter (by supporting fewer access modes). This means that restricting the set of access modes supported by a segment before sharing it with other clients is generally a good practice if the creator of the segment wants to retain some control over how the segment is going to be accessed.

## Memory segment views

Memory segments support views. For instance, it is possible to alter the set of supported access modes, by creating an immutable view of a memory segment, as follows:

>     MemorySegment segment = ...
>     MemorySegment roSegment = segment.withAccessModes(segment.accessModes() & ~WRITE);

It is also possible to create views whose spatial bounds are stricter than the ones of the original segment (see `asSlice(long, long)`).

Temporal bounds of the original segment are inherited by the view; that is, closing a segment view, such as a sliced view, will cause the original segment to be closed; as such special care must be taken when sharing views between multiple clients. If a client want to protect itself against early closure of a segment by another actor, it is the responsibility of that client to take protective measures, such as removing `CLOSE` from the set of supported access modes, before sharing the view with another client.

To allow for interoperability with existing code, a byte buffer view can be obtained from a memory segment (see `asByteBuffer()`). This can be useful, for instance, for those clients that want to keep using the `ByteBuffer` API, but need to operate on large memory segments. Byte buffers obtained in such a way support the same spatial and temporal access restrictions associated to the memory segment from which they originated.

## Thread confinement

Memory segments support strong thread-confinement guarantees. Upon creation, they are assigned an owner thread, typically the thread which initiated the creation operation. After creation, only the owner thread will be allowed to directly manipulate the memory segment (e.g. close the memory segment) or access the underlying memory associated with the segment using a memory access var handle. Any attempt to perform such operations from a thread other than the owner thread will result in a runtime failure.

Memory segments support serial thread confinement; that is, ownership of a memory segment can change (see `withOwnerThread(Thread)`). This allows, for instance, for two threads `A` and `B` to share a segment in a controlled, cooperative and race-free fashion.

In some cases, it might be useful for multiple threads to process the contents of the same memory segment concurrently (e.g. in the case of parallel processing); while memory segments provide strong confinement guarantees, it is possible to obtain a `Spliterator` from a segment, which can be used to slice the segment and allow multiple thread to work in parallel on disjoint segment slices (this assumes that the access mode `ACQUIRE` is set). For instance, the following code can be used to sum all int values in a memory segment in parallel:

>     MemorySegment segment = ...
>     SequenceLayout SEQUENCE_LAYOUT = MemoryLayout.ofSequence(1024, MemoryLayouts.JAVA_INT);
>     VarHandle VH_int = SEQUENCE_LAYOUT.elementLayout().varHandle(int.class);
>     int sum = StreamSupport.stream(MemorySegment.spliterator(segment, SEQUENCE_LAYOUT), true)
>                            .mapToInt(s -> (int)VH_int.get(s.baseAddress()))
>                            .sum();

API Note:
  In the future, if the Java language permits, `MemorySegment` may become a `sealed` interface, which would prohibit subclassing except by `MappedMemorySegment` and other explicitly permitted subtypes.
Implementation Requirements:
  Implementations of this interface are immutable, thread-safe and value-based.

- ## Field Summary

  Fields
  Modifier and Type | Field | Description
  --- | --- | ---
  `static int` | `ACQUIRE` | Acquire access mode; this segment support sharing with threads other than the owner thread, via spliterator (see `spliterator(MemorySegment, SequenceLayout)`).
  `static int` | `ALL_ACCESS` | Default access mode; this is a union of all the access modes supported by memory segments.
  `static int` | `CLOSE` | Close access mode; calling `close()` is supported by a segment which supports this access mode.
  `static int` | `HANDOFF` | Handoff access mode; this segment support serial thread-confinement via thread ownership changes (see `withOwnerThread(Thread)`).
  `static int` | `READ` | Read access mode; read operations are supported by a segment which supports this access mode.
  `static int` | `WRITE` | Write access mode; write operations are supported by a segment which supports this access mode.

- ## Method Summary

  Modifier and Type | Method | Description
  --- | --- | ---
  `int` | `accessModes()` | Returns the access modes associated with this segment; the result is represented as ORed values from `READ`, `WRITE`, `CLOSE`, `ACQUIRE` and `HANDOFF`.
  `static MemorySegment` | `allocateNative​(long bytesSize)` | Creates a new native memory segment that models a newly allocated block of off-heap memory with given size (in bytes).
  `static MemorySegment` | `allocateNative​(long bytesSize, long alignmentBytes)` | Creates a new native memory segment that models a newly allocated block of off-heap memory with given size and alignment constraint (in bytes).
  `static MemorySegment` | `allocateNative​(MemoryLayout layout)` | Creates a new native memory segment that models a newly allocated block of off-heap memory with given layout.
  `ByteBuffer` | `asByteBuffer()` | Wraps this segment in a `ByteBuffer`.
  `MemorySegment` | `asSlice​(long offset, long newSize)` | Obtains a new memory segment view whose base address is the same as the base address of this segment plus a given offset, and whose new size is specified by the given argument.
  `MemoryAddress` | `baseAddress()` | The base memory address associated with this memory segment.
  `long` | `byteSize()` | The size (in bytes) of this memory segment.
  `void` | `close()` | Closes this memory segment.
  `void` | `copyFrom​(MemorySegment src)` | Performs a bulk copy from given source segment to this segment.
  `MemorySegment` | `fill​(byte value)` | Fills a value into this memory segment.
  `boolean` | `hasAccessModes​(int accessModes)` | Does this segment support a given set of access modes?
  `boolean` | `isAlive()` | Is this segment alive?
  `static MappedMemorySegment` | `mapFromPath​(Path path, long bytesOffset, long bytesSize, FileChannel.MapMode mapMode)` | Creates a new mapped memory segment that models a memory-mapped region of a file from a given path.
  `long` | `mismatch​(MemorySegment other)` | Finds and returns the offset, in bytes, of the first mismatch between this segment and a given other segment.
  `static MemorySegment` | `ofArray​(byte[] arr)` | Creates a new array memory segment that models the memory associated with a given heap-allocated byte array.
  `static MemorySegment` | `ofArray​(char[] arr)` | Creates a new array memory segment that models the memory associated with a given heap-allocated char array.
  `static MemorySegment` | `ofArray​(double[] arr)` | Creates a new array memory segment that models the memory associated with a given heap-allocated double array.
  `static MemorySegment` | `ofArray​(float[] arr)` | Creates a new array memory segment that models the memory associated with a given heap-allocated float array.
  `static MemorySegment` | `ofArray​(int[] arr)` | Creates a new array memory segment that models the memory associated with a given heap-allocated int array.
  `static MemorySegment` | `ofArray​(long[] arr)` | Creates a new array memory segment that models the memory associated with a given heap-allocated long array.
  `static MemorySegment` | `ofArray​(short[] arr)` | Creates a new array memory segment that models the memory associated with a given heap-allocated short array.
  `static MemorySegment` | `ofByteBuffer​(ByteBuffer bb)` | Creates a new buffer memory segment that models the memory associated with the given byte buffer.
  `static MemorySegment` | `ofNativeRestricted​(MemoryAddress addr, long bytesSize, Thread owner, Runnable cleanup, Object attachment)` | Returns a new native memory segment with given base address and size; the returned segment has its own temporal bounds, and can therefore be closed; closing such a segment can optionally result in calling an user-provided cleanup action.
  `Thread` | `ownerThread()` | The thread owning this segment.
  `static <S extends MemorySegment> Spliterator<S>` | `spliterator​(S segment, SequenceLayout layout)` | Returns a spliterator for the given memory segment.
  `byte[]` | `toByteArray()` | Copy the contents of this memory segment into a fresh byte array.
  `MemorySegment` | `withAccessModes​(int accessModes)` | Obtains a segment view with specific access modes.
  `MemorySegment` | `withOwnerThread​(Thread newOwner)` | Obtains a new memory segment backed by the same underlying memory region as this segment, but with different owner thread.

- ## Field Details

  - ### READ

    static final int READ
    Read access mode; read operations are supported by a segment which supports this access mode.
    See Also:
      `accessModes()`, `withAccessModes(int)`, Constant Field Values

  - ### WRITE

    static final int WRITE
    Write access mode; write operations are supported by a segment which supports this access mode.
    See Also:
      `accessModes()`, `withAccessModes(int)`, Constant Field Values

  - ### CLOSE

    static final int CLOSE
    Close access mode; calling `close()` is supported by a segment which supports this access mode.
    See Also:
      `accessModes()`, `withAccessModes(int)`, Constant Field Values

  - ### ACQUIRE

    static final int ACQUIRE
    Acquire access mode; this segment support sharing with threads other than the owner thread, via spliterator (see `spliterator(MemorySegment, SequenceLayout)`).
    See Also:
      `accessModes()`, `withAccessModes(int)`, Constant Field Values

  - ### HANDOFF

    static final int HANDOFF
    Handoff access mode; this segment support serial thread-confinement via thread ownership changes (see `withOwnerThread(Thread)`).
    See Also:
      `accessModes()`, `withAccessModes(int)`, Constant Field Values

  - ### ALL_ACCESS

    static final int ALL_ACCESS
    Default access mode; this is a union of all the access modes supported by memory segments.
    See Also:
      `accessModes()`, `withAccessModes(int)`, Constant Field Values

- ## Method Details

  - ### baseAddress

    MemoryAddress baseAddress()
    The base memory address associated with this memory segment. The returned address is a checked memory address and can therefore be used in derefrence operations (see `MemoryAddress`).
    Returns:
      The base memory address.

  - ### spliterator

    static <S extends MemorySegment> Spliterator<S> spliterator​(S segment, SequenceLayout layout)
    Returns a spliterator for the given memory segment. The returned spliterator reports `Spliterator.SIZED`, `Spliterator.SUBSIZED`, `Spliterator.IMMUTABLE`, `Spliterator.NONNULL` and `Spliterator.ORDERED` characteristics.

    The returned spliterator splits the segment according to the specified sequence layout; that is, if the supplied layout is a sequence layout whose element count is `N`, then calling `Spliterator.trySplit()` will result in a spliterator serving approximatively `N/2` elements (depending on whether N is even or not). As such, splitting is possible as long as `N >= 2`. The spliterator returns segments that feature the same access modes as the given segment less the `CLOSE` access mode.

    The returned spliterator effectively allows to slice a segment into disjoint sub-segments, which can then be processed in parallel by multiple threads (if the access mode `ACQUIRE` is set). While closing the segment (see `close()`) during pending concurrent execution will generally fail with an exception, it is possible to close a segment when a spliterator has been obtained but no thread is actively working on it using `Spliterator.tryAdvance(Consumer)`; in such cases, any subsequent call to `Spliterator.tryAdvance(Consumer)` will fail with an exception.

    Type Parameters:
      `S` - the memory segment type
    Parameters:
      `segment` - the segment to be used for splitting.
      `layout` - the layout to be used for splitting.
    Returns:
      the element spliterator for this segment
    Throws:
      `IllegalStateException` - if the segment is not alive, or if access occurs from a thread other than the thread owning this segment

  - ### ownerThread

    Thread ownerThread()
    The thread owning this segment.
    Returns:
      the thread owning this segment.

  - ### withOwnerThread

    MemorySegment withOwnerThread​(Thread newOwner)
    Obtains a new memory segment backed by the same underlying memory region as this segment, but with different owner thread. As a side-effect, this segment will be marked as not alive, and subsequent operations on this segment will result in runtime errors.

    Write accesses to the segment's content happens-before hand-over from the current owner thread to the new owner thread, which in turn happens before read accesses to the segment's contents on the new owner thread.

    Parameters:
      `newOwner` - the new owner thread.
    Returns:
      a new memory segment backed by the same underlying memory region as this segment, owned by `newOwner`.
    Throws:
      `IllegalStateException` - if this segment is not alive, or if access occurs from a thread other than the thread owning this segment, or if the segment cannot be closed because it is being operated upon by a different thread (see `spliterator(MemorySegment, SequenceLayout)`).
      `NullPointerException` - if `newOwner == null`
      `IllegalArgumentException` - if the segment is already a confined segment owner by `newOnwer`.
      `UnsupportedOperationException` - if this segment does not support the `HANDOFF` access mode.

  - ### byteSize

    long byteSize()
    The size (in bytes) of this memory segment.
    Returns:
      The size (in bytes) of this memory segment.

  - ### withAccessModes

    MemorySegment withAccessModes​(int accessModes)
    Obtains a segment view with specific access modes. Supported access modes are `READ`, `WRITE`, `CLOSE`, `ACQUIRE` and `HANDOFF`. It is generally not possible to go from a segment with stricter access modes to one with less strict access modes. For instance, attempting to add `WRITE` access mode to a read-only segment will be met with an exception.
    Parameters:
      `accessModes` - an ORed mask of zero or more access modes.
    Returns:
      a segment view with specific access modes.
    Throws:
      `IllegalArgumentException` - when `mask` is an access mask which is less strict than the one supported by this segment, or when `mask` contains bits not associated with any of the supported access modes.

  - ### hasAccessModes

    boolean hasAccessModes​(int accessModes)
    Does this segment support a given set of access modes?
    Parameters:
      `accessModes` - an ORed mask of zero or more access modes.
    Returns:
      true, if the access modes in `accessModes` are stricter than the ones supported by this segment.
    Throws:
      `IllegalArgumentException` - when `mask` contains bits not associated with any of the supported access modes.

  - ### accessModes

    int accessModes()
    Returns the access modes associated with this segment; the result is represented as ORed values from `READ`, `WRITE`, `CLOSE`, `ACQUIRE` and `HANDOFF`.
    Returns:
      the access modes associated with this segment.

  - ### asSlice

    MemorySegment asSlice​(long offset, long newSize)
    Obtains a new memory segment view whose base address is the same as the base address of this segment plus a given offset, and whose new size is specified by the given argument.
    Parameters:
      `offset` - The new segment base offset (relative to the current segment base address), specified in bytes.
      `newSize` - The new segment size, specified in bytes.
    Returns:
      a new memory segment view with updated base/limit addresses.
    Throws:
      `IndexOutOfBoundsException` - if `offset < 0`, `offset > byteSize()`, `newSize < 0`, or `newSize > byteSize() - offset`

  - ### isAlive

    boolean isAlive()
    Is this segment alive?
    Returns:
      true, if the segment is alive.
    See Also:
      `close()`

  - ### close

    void close()
    Closes this memory segment. Once a memory segment has been closed, any attempt to use the memory segment, or to access any `MemoryAddress` instance associated with it will fail with `IllegalStateException`. Depending on the kind of memory segment being closed, calling this method further triggers deallocation of all the resources associated with the memory segment.
    Specified by:
      `close` in interface `AutoCloseable`
    Throws:
      `IllegalStateException` - if this segment is not alive, or if access occurs from a thread other than the thread owning this segment, or if the segment cannot be closed because it is being operated upon by a different thread (see `spliterator(MemorySegment, SequenceLayout)`).
      `UnsupportedOperationException` - if this segment does not support the `CLOSE` access mode.

  - ### fill

    MemorySegment fill​(byte value)
    Fills a value into this memory segment.

    More specifically, the given value is filled into each address of this segment. Equivalent to (but likely more efficient than) the following code:

        byteHandle = MemoryLayout.ofSequence(MemoryLayouts.JAVA_BYTE)
                 .varHandle(byte.class, MemoryLayout.PathElement.sequenceElement());
        for (long l = 0; l < segment.byteSize(); l++) {
             byteHandle.set(segment.baseAddress(), l, value);
        }

    without any regard or guarantees on the ordering of particular memory elements being set.

    Fill can be useful to initialize or reset the memory of a segment.

    Parameters:
      `value` - the value to fill into this segment
    Returns:
      this memory segment
    Throws:
      `IllegalStateException` - if this segment is not alive, or if access occurs from a thread other than the thread owning this segment
      `UnsupportedOperationException` - if this segment does not support the `WRITE` access mode

  - ### copyFrom

    void copyFrom​(MemorySegment src)
    Performs a bulk copy from given source segment to this segment. More specifically, the bytes at offset `0` through `src.byteSize() - 1` in the source segment are copied into this segment at offset `0` through `src.byteSize() - 1`. If the source segment overlaps with this segment, then the copying is performed as if the bytes at offset `0` through `src.byteSize() - 1` in the source segment were first copied into a temporary segment with size `bytes`, and then the contents of the temporary segment were copied into this segment at offset `0` through `src.byteSize() - 1`.

    The result of a bulk copy is unspecified if, in the uncommon case, the source segment and this segment do not overlap, but refer to overlapping regions of the same backing storage using different addresses. For example, this may occur if the same file is `mapped` to two segments.

    Parameters:
      `src` - the source segment.
    Throws:
      `IndexOutOfBoundsException` - if `src.byteSize() > this.byteSize()`.
      `IllegalStateException` - if either the source segment or this segment have been already closed, or if access occurs from a thread other than the thread owning either segment.
      `UnsupportedOperationException` - if either the source segment or this segment do not feature required access modes; more specifically, `src` should feature at least the `READ` access mode, while this segment should feature at least the `WRITE` access mode.

  - ### mismatch

    long mismatch​(MemorySegment other)
    Finds and returns the offset, in bytes, of the first mismatch between this segment and a given other segment. The offset is relative to the `base address` of each segment and will be in the range of 0 (inclusive) up to the `size` (in bytes) of the smaller memory segment (exclusive).

    If the two segments share a common prefix then the returned offset is the length of the common prefix and it follows that there is a mismatch between the two segments at that offset within the respective segments. If one segment is a proper prefix of the other then the returned offset is the smaller of the segment sizes, and it follows that the offset is only valid for the larger segment. Otherwise, there is no mismatch and `-1` is returned.

    Parameters:
      `other` - the segment to be tested for a mismatch with this segment
    Returns:
      the relative offset, in bytes, of the first mismatch between this and the given other segment, otherwise -1 if no mismatch
    Throws:
      `IllegalStateException` - if either this segment of the other segment have been already closed, or if access occurs from a thread other than the thread owning either segment
      `UnsupportedOperationException` - if either this segment or the other segment does not feature at least the `READ` access mode

  - ### asByteBuffer

    ByteBuffer asByteBuffer()
    Wraps this segment in a `ByteBuffer`. Some of the properties of the returned buffer are linked to the properties of this segment. For instance, if this segment is immutable (e.g. the segment has access mode `READ` but not `WRITE`), then the resulting buffer is read-only (see `Buffer.isReadOnly()`. Additionally, if this is a native memory segment, the resulting buffer is direct (see `ByteBuffer.isDirect()`).

    The life-cycle of the returned buffer will be tied to that of this segment. That means that if the this segment is closed (see `close()`, accessing the returned buffer will throw an `IllegalStateException`.

    The resulting buffer's byte order is `ByteOrder.BIG_ENDIAN`; this can be changed using `ByteBuffer.order(java.nio.ByteOrder)`.

    Returns:
      a `ByteBuffer` view of this memory segment.
    Throws:
      `UnsupportedOperationException` - if this segment cannot be mapped onto a `ByteBuffer` instance, e.g. because it models an heap-based segment that is not based on a `byte[]`), or if its size is greater than `Integer.MAX_VALUE`, or if the segment does not support the `READ` access mode.

  - ### toByteArray

    byte[] toByteArray()
    Copy the contents of this memory segment into a fresh byte array.
    Returns:
      a fresh byte array copy of this memory segment.
    Throws:
      `UnsupportedOperationException` - if this segment does not feature the `READ` access mode, or if this segment's contents cannot be copied into a `byte` instance, e.g. its size is greater than `Integer.MAX_VALUE`,
      `IllegalStateException` - if this segment has been closed, or if access occurs from a thread other than the thread owning this segment.

  - ### ofByteBuffer

    static MemorySegment ofByteBuffer​(ByteBuffer bb)
    Creates a new buffer memory segment that models the memory associated with the given byte buffer. The segment starts relative to the buffer's position (inclusive) and ends relative to the buffer's limit (exclusive).

    The segment will feature all access modes (see `ALL_ACCESS`), unless the given buffer is read-only in which case the segment will not feature the `WRITE` access mode.

    The resulting memory segment keeps a reference to the backing buffer, to ensure it remains reachable for the life-time of the segment.

    Parameters:
      `bb` - the byte buffer backing the buffer memory segment.
    Returns:
      a new buffer memory segment.

  - ### ofArray

    static MemorySegment ofArray​(byte[] arr)
    Creates a new array memory segment that models the memory associated with a given heap-allocated byte array.

    The resulting memory segment keeps a reference to the backing array, to ensure it remains reachable for the life-time of the segment. The segment will feature all access modes (see `ALL_ACCESS`).

    Parameters:
      `arr` - the primitive array backing the array memory segment.
    Returns:
      a new array memory segment.

  - ### ofArray

    static MemorySegment ofArray​(char[] arr)
    Creates a new array memory segment that models the memory associated with a given heap-allocated char array.

    The resulting memory segment keeps a reference to the backing array, to ensure it remains reachable for the life-time of the segment. The segment will feature all access modes (see `ALL_ACCESS`).

    Parameters:
      `arr` - the primitive array backing the array memory segment.
    Returns:
      a new array memory segment.

  - ### ofArray

    static MemorySegment ofArray​(short[] arr)
    Creates a new array memory segment that models the memory associated with a given heap-allocated short array.

    The resulting memory segment keeps a reference to the backing array, to ensure it remains reachable for the life-time of the segment. The segment will feature all access modes (see `ALL_ACCESS`).

    Parameters:
      `arr` - the primitive array backing the array memory segment.
    Returns:
      a new array memory segment.

  - ### ofArray

    static MemorySegment ofArray​(int[] arr)
    Creates a new array memory segment that models the memory associated with a given heap-allocated int array.

    The resulting memory segment keeps a reference to the backing array, to ensure it remains reachable for the life-time of the segment. The segment will feature all access modes.

    Parameters:
      `arr` - the primitive array backing the array memory segment.
    Returns:
      a new array memory segment.

  - ### ofArray

    static MemorySegment ofArray​(float[] arr)
    Creates a new array memory segment that models the memory associated with a given heap-allocated float array.

    The resulting memory segment keeps a reference to the backing array, to ensure it remains reachable for the life-time of the segment. The segment will feature all access modes (see `ALL_ACCESS`).

    Parameters:
      `arr` - the primitive array backing the array memory segment.
    Returns:
      a new array memory segment.

  - ### ofArray

    static MemorySegment ofArray​(long[] arr)
    Creates a new array memory segment that models the memory associated with a given heap-allocated long array.

    The resulting memory segment keeps a reference to the backing array, to ensure it remains reachable for the life-time of the segment. The segment will feature all access modes (see `ALL_ACCESS`).

    Parameters:
      `arr` - the primitive array backing the array memory segment.
    Returns:
      a new array memory segment.

  - ### ofArray

    static MemorySegment ofArray​(double[] arr)
    Creates a new array memory segment that models the memory associated with a given heap-allocated double array.

    The resulting memory segment keeps a reference to the backing array, to ensure it remains reachable for the life-time of the segment. The segment will feature all access modes (see `ALL_ACCESS`).

    Parameters:
      `arr` - the primitive array backing the array memory segment.
    Returns:
      a new array memory segment.

  - ### allocateNative

    static MemorySegment allocateNative​(MemoryLayout layout)
    Creates a new native memory segment that models a newly allocated block of off-heap memory with given layout.

    This is equivalent to the following code:

    >         allocateNative(layout.bytesSize(), layout.bytesAlignment());

    Implementation Note:
      The block of off-heap memory associated with the returned native memory segment is initialized to zero. Moreover, a client is responsible to call the `close()` on a native memory segment, to make sure the backing off-heap memory block is deallocated accordingly. Failure to do so will result in off-heap memory leaks.
    Parameters:
      `layout` - the layout of the off-heap memory block backing the native memory segment.
    Returns:
      a new native memory segment.
    Throws:
      `IllegalArgumentException` - if the specified layout has illegal size or alignment constraint.

  - ### allocateNative

    static MemorySegment allocateNative​(long bytesSize)
    Creates a new native memory segment that models a newly allocated block of off-heap memory with given size (in bytes).

    This is equivalent to the following code:

    >     allocateNative(bytesSize, 1);

    Implementation Note:
      The block of off-heap memory associated with the returned native memory segment is initialized to zero. Moreover, a client is responsible to call the `close()` on a native memory segment, to make sure the backing off-heap memory block is deallocated accordingly. Failure to do so will result in off-heap memory leaks.
    Parameters:
      `bytesSize` - the size (in bytes) of the off-heap memory block backing the native memory segment.
    Returns:
      a new native memory segment.
    Throws:
      `IllegalArgumentException` - if `bytesSize < 0`.

  - ### mapFromPath

    static MappedMemorySegment mapFromPath​(Path path, long bytesOffset, long bytesSize, FileChannel.MapMode mapMode) throws IOException
    Creates a new mapped memory segment that models a memory-mapped region of a file from a given path.

    The segment will feature all access modes (see `ALL_ACCESS`), unless the given mapping mode is READ_ONLY, in which case the segment will not feature the `WRITE` access mode.

    Implementation Note:
      When obtaining a mapped segment from a newly created file, the initialization state of the contents of the block of mapped memory associated with the returned mapped memory segment is unspecified and should not be relied upon.
    Parameters:
      `path` - the path to the file to memory map.
      `bytesOffset` - the offset (expressed in bytes) within the file at which the mapped segment is to start.
      `bytesSize` - the size (in bytes) of the mapped memory backing the memory segment.
      `mapMode` - a file mapping mode, see `FileChannel.map(FileChannel.MapMode, long, long)`; the chosen mapping mode might affect the behavior of the returned memory mapped segment (see `MappedMemorySegment.force()`).
    Returns:
      a new mapped memory segment.
    Throws:
      `IllegalArgumentException` - if `bytesOffset < 0`.
      `IllegalArgumentException` - if `bytesSize < 0`.
      `UnsupportedOperationException` - if an unsupported map mode is specified.
      `IOException` - if the specified path does not point to an existing file, or if some other I/O error occurs.

  - ### allocateNative

    static MemorySegment allocateNative​(long bytesSize, long alignmentBytes)
    Creates a new native memory segment that models a newly allocated block of off-heap memory with given size and alignment constraint (in bytes). The segment will feature all access modes (see `ALL_ACCESS`).
    Implementation Note:
      The block of off-heap memory associated with the returned native memory segment is initialized to zero. Moreover, a client is responsible to call the `close()` on a native memory segment, to make sure the backing off-heap memory block is deallocated accordingly. Failure to do so will result in off-heap memory leaks.
    Parameters:
      `bytesSize` - the size (in bytes) of the off-heap memory block backing the native memory segment.
      `alignmentBytes` - the alignment constraint (in bytes) of the off-heap memory block backing the native memory segment.
    Returns:
      a new native memory segment.
    Throws:
      `IllegalArgumentException` - if `bytesSize < 0`, `alignmentBytes < 0`, or if `alignmentBytes` is not a power of 2.

  - ### ofNativeRestricted

    static MemorySegment ofNativeRestricted​(MemoryAddress addr, long bytesSize, Thread owner, Runnable cleanup, Object attachment)
    Returns a new native memory segment with given base address and size; the returned segment has its own temporal bounds, and can therefore be closed; closing such a segment can optionally result in calling an user-provided cleanup action. This method can be very useful when interacting with custom native memory sources (e.g. custom allocators, GPU memory, etc.), where an address to some underlying memory region is typically obtained from native code (often as a plain `long` value). The segment will feature all access modes (see `ALL_ACCESS`).

    This method is restricted. Restricted methods are unsafe, and, if used incorrectly, their use might crash the JVM or, worse, silently result in memory corruption. Thus, clients should refrain from depending on restricted methods, and use safe and supported functionalities, where possible.

    Parameters:
      `addr` - the desired base address
      `bytesSize` - the desired size.
      `owner` - the desired owner thread. If `owner == null`, the returned segment is not confined.
      `cleanup` - a cleanup action to be executed when the `close()` method is called on the returned segment. If `cleanup == null`, no cleanup action is executed.
      `attachment` - an object that must be kept alive by the returned segment; this can be useful when the returned segment depends on memory which could be released if a certain object is determined to be unreacheable. In most cases this will be set to `null`.
    Returns:
      a new native memory segment with given base address, size, owner, cleanup action and object attachment.
    Throws:
      `IllegalArgumentException` - if `bytesSize <= 0`.
      `UnsupportedOperationException` - if `addr` is associated with an heap segment.
      `IllegalAccessError` - if the runtime property `foreign.restricted` is not set to either `permit`, `warn` or `debug` (the default value is set to `deny`).
      `NullPointerException` - if `addr == null`.