/*
 *  Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
 *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 *  This code is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License version 2 only, as
 *  published by the Free Software Foundation.  Oracle designates this
 *  particular file as subject to the "Classpath" exception as provided
 *  by Oracle in the LICENSE file that accompanied this code.
 *
 *  This code is distributed in the hope that it will be useful, but WITHOUT
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 *  version 2 for more details (a copy is included in the LICENSE file that
 *  accompanied this code).
 *
 *  You should have received a copy of the GNU General Public License version
 *  2 along with this work; if not, write to the Free Software Foundation,
 *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 *   Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 *  or visit www.oracle.com if you need additional information or have any
 *  questions.
 *
 */

package jdk.incubator.foreign;

import java.nio.ByteBuffer;

import jdk.internal.foreign.Utils;

import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.Path;

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 checks 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, MapMode). Such memory segments are called mapped memory segments.

Closing a memory segment

Memory segments are closed explicitly (see close()). In general when a segment is closed, all off-heap resources associated with it are released; this has different meanings 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 an acquired memory segment does not result in the release of resources (see the section on thread confinement for more details)
  • 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.

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.

If a memory segment S owned by thread A needs to be used by thread B, B needs to explicitly acquire S, which will create a so called acquired memory segment owned by B (see acquire()) backed by the same resources as S. A memory segment can be acquired multiple times by one or more threads; in that case, a memory segment S cannot be closed until all the acquired memory segments derived from S have been closed. Furthermore, closing an acquired memory segment does not trigger any deallocation action. It is therefore important that clients remember to explicitly close the original segment from which the acquired memory segments have been obtained in order to truly ensure that off-heap resources associated with the memory segment are released.

Memory segment views

Memory segments support views. It is possible to create an immutable view of a memory segment (see asReadOnly()) which does not support write operations. 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 calling acquire() 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 address from which they originated.

API Note:In the future, if the Java language permits, MemorySegment may become a sealed interface, which would prohibit subclassing except by explicitly permitted types.
Implementation Requirements: Implementations of this interface are immutable and thread-safe.
/** * 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 <em>outside</em> the boundaries of the memory segment being accessed. Temporal checks ensure that memory access * operations on a segment cannot occur after a memory segment has been closed (see {@link MemorySegment#close()}). * <p> * All implementations of this interface must be <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>; * use of identity-sensitive operations (including reference equality ({@code ==}), identity hash code, or synchronization) on * instances of {@code MemorySegment} may have unpredictable results and should be avoided. The {@code equals} method should * be used for comparisons. * <p> * Non-platform classes should not implement {@linkplain MemorySegment} directly. * * <h2>Constructing memory segments from different sources</h2> * * 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 {@link MemorySegment#allocateNative(MemoryLayout)}, * {@link MemorySegment#allocateNative(long)} and {@link MemorySegment#allocateNative(long, long)}). Memory segments obtained * in this way are called <em>native memory segments</em>. * <p> * 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. {@link MemorySegment#ofArray(int[])}). Memory segments obtained * in this way are called <em>array memory segments</em>. * <p> * It is possible to obtain a memory segment backed by an existing Java byte buffer (see {@link ByteBuffer}), * using the factory method {@link MemorySegment#ofByteBuffer(ByteBuffer)}. * Memory segments obtained in this way are called <em>buffer memory segments</em>. 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 {@link ByteBuffer#allocateDirect(int)} method will be backed * by native memory. * <p> * Finally, it is also possible to obtain a memory segment backed by a memory-mapped file using the factory method * {@link MemorySegment#mapFromPath(Path, long, FileChannel.MapMode)}. Such memory segments are called <em>mapped memory segments</em>. * * <h2>Closing a memory segment</h2> * * Memory segments are closed explicitly (see {@link MemorySegment#close()}). In general when a segment is closed, all off-heap * resources associated with it are released; this has different meanings depending on the kind of memory segment being * considered: * <ul> * <li>closing a native memory segment results in <em>freeing</em> the native memory associated with it</li> * <li>closing a mapped memory segment results in the backing memory-mapped file to be unmapped</li> * <li>closing an acquired memory segment <b>does not</b> result in the release of resources * (see the section on <a href="#thread-confinement">thread confinement</a> for more details)</li> * <li>closing a buffer, or a heap segment does not have any side-effect, other than marking the segment * as <em>not alive</em> (see {@link MemorySegment#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.</li> * </ul> * * <h2><a id = "thread-confinement">Thread confinement</a></h2> * * Memory segments support strong thread-confinement guarantees. Upon creation, they are assigned an <em>owner thread</em>, * 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. * <p> * If a memory segment S owned by thread A needs to be used by thread B, B needs to explicitly <em>acquire</em> S, * which will create a so called <em>acquired</em> memory segment owned by B (see {@link #acquire()}) backed by the same resources * as S. A memory segment can be acquired multiple times by one or more threads; in that case, a memory segment S cannot * be closed until all the acquired memory segments derived from S have been closed. Furthermore, closing an acquired * memory segment does <em>not</em> trigger any deallocation action. It is therefore important that clients remember to * explicitly close the original segment from which the acquired memory segments have been obtained in order to truly * ensure that off-heap resources associated with the memory segment are released. * * <h2>Memory segment views</h2> * * Memory segments support <em>views</em>. It is possible to create an <em>immutable</em> view of a memory segment * (see {@link MemorySegment#asReadOnly()}) which does not support write operations. It is also possible to create views * whose spatial bounds are stricter than the ones of the original segment (see {@link MemorySegment#asSlice(long, long)}). * <p> * 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 calling * {@link MemorySegment#acquire()} before sharing the view with another client. * <p> * To allow for interoperability with existing code, a byte buffer view can be obtained from a memory segment * (see {@link #asByteBuffer()}). This can be useful, for instance, for those clients that want to keep using the * {@link 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 address from which they originated. * * @apiNote In the future, if the Java language permits, {@link MemorySegment} * may become a {@code sealed} interface, which would prohibit subclassing except by * explicitly permitted types. * * @implSpec * Implementations of this interface are immutable and thread-safe. */
public interface MemorySegment extends AutoCloseable {
The base memory address associated with this memory segment.
Returns:The base memory address.
/** * The base memory address associated with this memory segment. * @return The base memory address. */
MemoryAddress baseAddress();
Obtains an acquired memory segment which can be used to access memory associated with this segment from the current thread. As a side-effect, this segment cannot be closed until the acquired view has been closed too (see close()).
Throws:
Returns:an acquired memory segment which can be used to access memory associated with this segment from the current thread.
/** * Obtains an <a href="#thread-confinement">acquired</a> memory segment which can be used to access memory associated * with this segment from the current thread. As a side-effect, this segment cannot be closed until the acquired * view has been closed too (see {@link #close()}). * @return an <a href="#thread-confinement">acquired</a> memory segment which can be used to access memory associated * with this segment from the current thread. * @throws IllegalStateException if this segment has been closed. */
MemorySegment acquire();
The thread owning this segment.
Returns:the thread owning this segment.
/** * The thread owning this segment. * @return the thread owning this segment. */
Thread ownerThread();
The size (in bytes) of this memory segment.
Returns:The size (in bytes) of this memory segment.
/** * The size (in bytes) of this memory segment. * @return The size (in bytes) of this memory segment. */
long byteSize();
Obtains a read-only view of this segment. An attempt to write memory associated with a read-only memory segment will fail with UnsupportedOperationException.
Throws:
  • IllegalStateException – if this segment has been closed, or if access occurs from a thread other than the thread owning this segment.
Returns:a read-only view of this segment.
/** * Obtains a read-only view of this segment. An attempt to write memory associated with a read-only memory segment * will fail with {@link UnsupportedOperationException}. * @return a read-only view of this segment. * @throws IllegalStateException if this segment has been closed, or if access occurs from a thread other than the * thread owning this segment. */
MemorySegment asReadOnly();
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.
Params:
  • offset – The new segment base offset (relative to the current segment base address), specified in bytes.
  • newSize – The new segment size, specified in bytes.
Throws:
  • IndexOutOfBoundsException – if offset < 0, offset > byteSize(), newSize < 0, or newSize > byteSize() - offset
  • IllegalStateException – if this segment has been closed, or if access occurs from a thread other than the thread owning this segment.
Returns:a new memory segment view with updated base/limit addresses.
/** * 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. * @param offset The new segment base offset (relative to the current segment base address), specified in bytes. * @param newSize The new segment size, specified in bytes. * @return a new memory segment view with updated base/limit addresses. * @throws IndexOutOfBoundsException if {@code offset < 0}, {@code offset > byteSize()}, {@code newSize < 0}, or {@code newSize > byteSize() - offset} * @throws IllegalStateException if this segment has been closed, or if access occurs from a thread other than the * thread owning this segment. */
MemorySegment asSlice(long offset, long newSize);
Is this segment alive?
See Also:
Returns:true, if the segment is alive.
/** * Is this segment alive? * @return true, if the segment is alive. * @see MemorySegment#close() */
boolean isAlive();
Is this segment read-only?
See Also:
Returns:true, if the segment is read-only.
/** * Is this segment read-only? * @return true, if the segment is read-only. * @see MemorySegment#asReadOnly() */
boolean isReadOnly();
Closes this memory segment. Once a memory segment has been closed, any attempt to use the memory segment, or to access the memory associated with the segment will fail with IllegalStateException. Depending on the kind of memory segment being closed, calling this method further trigger deallocation of all the resources associated with the memory segment.
Throws:
  • IllegalStateException – if this segment has been closed, or if access occurs from a thread other than the thread owning this segment, or if existing acquired views of this segment are still in use (see acquire()).
/** * Closes this memory segment. Once a memory segment has been closed, any attempt to use the memory segment, * or to access the memory associated with the segment will fail with {@link IllegalStateException}. Depending on * the kind of memory segment being closed, calling this method further trigger deallocation of all the resources * associated with the memory segment. * @throws IllegalStateException if this segment has been closed, or if access occurs from a thread other than the * thread owning this segment, or if existing acquired views of this segment are still in use (see {@link MemorySegment#acquire()}). */
void close();
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 (see asReadOnly(), 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(ByteOrder).

Throws:
Returns:a ByteBuffer view of this memory segment.
/** * Wraps this segment in a {@link ByteBuffer}. Some of the properties of the returned buffer are linked to * the properties of this segment. For instance, if this segment is <em>immutable</em> * (see {@link MemorySegment#asReadOnly()}, then the resulting buffer is <em>read-only</em> * (see {@link ByteBuffer#isReadOnly()}. Additionally, if this is a native memory segment, the resulting buffer is * <em>direct</em> (see {@link ByteBuffer#isDirect()}). * <p> * 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 {@link MemorySegment#close()}, accessing the returned * buffer will throw an {@link IllegalStateException}. * <p> * The resulting buffer's byte order is {@link java.nio.ByteOrder#BIG_ENDIAN}; this can be changed using * {@link ByteBuffer#order(java.nio.ByteOrder)}. * * @return a {@link ByteBuffer} view of this memory segment. * @throws UnsupportedOperationException if this segment cannot be mapped onto a {@link ByteBuffer} instance, * e.g. because it models an heap-based segment that is not based on a {@code byte[]}), or if its size is greater * than {@link Integer#MAX_VALUE}. * @throws IllegalStateException if this segment has been closed, or if access occurs from a thread other than the * thread owning this segment. */
ByteBuffer asByteBuffer();
Copy the contents of this memory segment into a fresh byte array.
Throws:
Returns:a fresh byte array copy of this memory segment.
/** * Copy the contents of this memory segment into a fresh byte array. * @return a fresh byte array copy of this memory segment. * @throws UnsupportedOperationException if this segment's contents cannot be copied into a {@link byte[]} instance, * e.g. its size is greater than {@link Integer#MAX_VALUE}. * @throws IllegalStateException if this segment has been closed, or if access occurs from a thread other than the * thread owning this segment. */
byte[] toByteArray();
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 resulting memory segment keeps a reference to the backing buffer, to ensure it remains reachable for the life-time of the segment.

Params:
  • bb – the byte buffer backing the buffer memory segment.
Returns:a new buffer memory segment.
/** * 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). * <p> * The resulting memory segment keeps a reference to the backing buffer, to ensure it remains <em>reachable</em> * for the life-time of the segment. * * @param bb the byte buffer backing the buffer memory segment. * @return a new buffer memory segment. */
static MemorySegment ofByteBuffer(ByteBuffer bb) { return Utils.makeBufferSegment(bb); }
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.

Params:
  • arr – the primitive array backing the array memory segment.
Returns:a new array memory segment.
/** * Creates a new array memory segment that models the memory associated with a given heap-allocated byte array. * <p> * The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em> * for the life-time of the segment. * * @param arr the primitive array backing the array memory segment. * @return a new array memory segment. */
static MemorySegment ofArray(byte[] arr) { return Utils.makeArraySegment(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.

Params:
  • arr – the primitive array backing the array memory segment.
Returns:a new array memory segment.
/** * Creates a new array memory segment that models the memory associated with a given heap-allocated char array. * <p> * The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em> * for the life-time of the segment. * * @param arr the primitive array backing the array memory segment. * @return a new array memory segment. */
static MemorySegment ofArray(char[] arr) { return Utils.makeArraySegment(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.

Params:
  • arr – the primitive array backing the array memory segment.
Returns:a new array memory segment.
/** * Creates a new array memory segment that models the memory associated with a given heap-allocated short array. * <p> * The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em> * for the life-time of the segment. * * @param arr the primitive array backing the array memory segment. * @return a new array memory segment. */
static MemorySegment ofArray(short[] arr) { return Utils.makeArraySegment(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.

Params:
  • arr – the primitive array backing the array memory segment.
Returns:a new array memory segment.
/** * Creates a new array memory segment that models the memory associated with a given heap-allocated int array. * <p> * The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em> * for the life-time of the segment. * * @param arr the primitive array backing the array memory segment. * @return a new array memory segment. */
static MemorySegment ofArray(int[] arr) { return Utils.makeArraySegment(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.

Params:
  • arr – the primitive array backing the array memory segment.
Returns:a new array memory segment.
/** * Creates a new array memory segment that models the memory associated with a given heap-allocated float array. * <p> * The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em> * for the life-time of the segment. * * @param arr the primitive array backing the array memory segment. * @return a new array memory segment. */
static MemorySegment ofArray(float[] arr) { return Utils.makeArraySegment(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.

Params:
  • arr – the primitive array backing the array memory segment.
Returns:a new array memory segment.
/** * Creates a new array memory segment that models the memory associated with a given heap-allocated long array. * <p> * The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em> * for the life-time of the segment. * * @param arr the primitive array backing the array memory segment. * @return a new array memory segment. */
static MemorySegment ofArray(long[] arr) { return Utils.makeArraySegment(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.

Params:
  • arr – the primitive array backing the array memory segment.
Returns:a new array memory segment.
/** * Creates a new array memory segment that models the memory associated with a given heap-allocated double array. * <p> * The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em> * for the life-time of the segment. * * @param arr the primitive array backing the array memory segment. * @return a new array memory segment. */
static MemorySegment ofArray(double[] arr) { return Utils.makeArraySegment(arr); }
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());
Params:
  • layout – the layout of the off-heap memory block backing the native memory segment.
Throws:
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.
Returns:a new native memory segment.
/** * Creates a new native memory segment that models a newly allocated block of off-heap memory with given layout. * <p> * This is equivalent to the following code: * <blockquote><pre>{@code allocateNative(layout.bytesSize(), layout.bytesAlignment()); * }</pre></blockquote> * * @implNote 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 {@link MemorySegment#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. * * @param layout the layout of the off-heap memory block backing the native memory segment. * @return a new native memory segment. * @throws IllegalArgumentException if the specified layout has illegal size or alignment constraint. */
static MemorySegment allocateNative(MemoryLayout layout) { return allocateNative(layout.byteSize(), layout.byteAlignment()); }
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);
Params:
  • bytesSize – the size (in bytes) of the off-heap memory block backing the native memory segment.
Throws:
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.
Returns:a new native memory segment.
/** * Creates a new native memory segment that models a newly allocated block of off-heap memory with given size (in bytes). * <p> * This is equivalent to the following code: * <blockquote><pre>{@code allocateNative(bytesSize, 1); * }</pre></blockquote> * * @implNote 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 {@link MemorySegment#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. * * @param bytesSize the size (in bytes) of the off-heap memory block backing the native memory segment. * @return a new native memory segment. * @throws IllegalArgumentException if {@code bytesSize < 0}. */
static MemorySegment allocateNative(long bytesSize) { return allocateNative(bytesSize, 1); }
Creates a new mapped memory segment that models a memory-mapped region of a file from a given path.
Params:
  • path – the path to the file to memory map.
  • bytesSize – the size (in bytes) of the mapped memory backing the memory segment.
  • mapMode – a file mapping mode, see FileChannel.map(MapMode, long, long).
Throws:
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.
Returns:a new mapped memory segment.
/** * Creates a new mapped memory segment that models a memory-mapped region of a file from a given path. * * @implNote 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. * * @param path the path to the file to memory map. * @param bytesSize the size (in bytes) of the mapped memory backing the memory segment. * @param mapMode a file mapping mode, see {@link FileChannel#map(FileChannel.MapMode, long, long)}. * @return a new mapped memory segment. * @throws IllegalArgumentException if {@code bytesSize < 0}. * @throws UnsupportedOperationException if an unsupported map mode is specified. * @throws IOException if the specified path does not point to an existing file, or if some other I/O error occurs. */
static MemorySegment mapFromPath(Path path, long bytesSize, FileChannel.MapMode mapMode) throws IOException { return Utils.makeMappedSegment(path, bytesSize, mapMode); }
Creates a new native memory segment that models a newly allocated block of off-heap memory with given size and alignment constraint (in bytes).
Params:
  • 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.
Throws:
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.
Returns:a new native memory segment.
/** * Creates a new native memory segment that models a newly allocated block of off-heap memory with given size and * alignment constraint (in bytes). * * @implNote 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 {@link MemorySegment#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. * * @param bytesSize the size (in bytes) of the off-heap memory block backing the native memory segment. * @param alignmentBytes the alignment constraint (in bytes) of the off-heap memory block backing the native memory segment. * @return a new native memory segment. * @throws IllegalArgumentException if {@code bytesSize < 0}, {@code alignmentBytes < 0}, or if {@code alignmentBytes} * is not a power of 2. */
static MemorySegment allocateNative(long bytesSize, long alignmentBytes) { if (bytesSize <= 0) { throw new IllegalArgumentException("Invalid allocation size : " + bytesSize); } if (alignmentBytes < 0 || ((alignmentBytes & (alignmentBytes - 1)) != 0L)) { throw new IllegalArgumentException("Invalid alignment constraint : " + alignmentBytes); } return Utils.makeNativeSegment(bytesSize, alignmentBytes); } }