- All Superinterfaces:
AutoCloseable
public interface MemorySegment extends AutoCloseable
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 (seeallocateNative(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, FileChannel.MapMode)
. Such memory segments are called mapped memory segments.
Closing a memory segment
Memory segments are closed explicitly (seeclose()
). 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 (seeasReadOnly()
) 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 asealed
interface, which would prohibit subclassing except by explicitly permitted types. - Implementation Requirements:
- Implementations of this interface are immutable and thread-safe.
-
Method Summary
Modifier and Type Method Description MemorySegment
acquire()
Obtains an acquired memory segment which can be used to access memory associated with this segment from the current thread.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 aByteBuffer
.MemorySegment
asReadOnly()
Obtains a read-only view of this segment.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.boolean
isAlive()
Is this segment alive?boolean
isReadOnly()
Is this segment read-only?static MemorySegment
mapFromPath(Path path, long bytesSize, FileChannel.MapMode mapMode)
Creates a new mapped memory segment that models a memory-mapped region of a file from a given path.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.Thread
ownerThread()
The thread owning this segment.byte[]
toByteArray()
Copy the contents of this memory segment into a fresh byte array.
-
Method Details
-
baseAddress
MemoryAddress baseAddress()The base memory address associated with this memory segment.- Returns:
- The base memory address.
-
acquire
MemorySegment acquire()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 (seeclose()
).- Returns:
- an acquired 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.
-
ownerThread
Thread ownerThread()The thread owning this segment.- Returns:
- the thread owning this segment.
-
byteSize
long byteSize()The size (in bytes) of this memory segment.- Returns:
- The size (in bytes) of this memory segment.
-
asReadOnly
MemorySegment asReadOnly()Obtains a read-only view of this segment. An attempt to write memory associated with a read-only memory segment will fail withUnsupportedOperationException
.- Returns:
- 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.
-
asSlice
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
- ifoffset < 0
,offset > byteSize()
,newSize < 0
, ornewSize > byteSize() - offset
IllegalStateException
- if this segment has been closed, or if access occurs from a thread other than the thread owning this segment.
-
isAlive
boolean isAlive()Is this segment alive?- Returns:
- true, if the segment is alive.
- See Also:
close()
-
isReadOnly
boolean isReadOnly()Is this segment read-only?- Returns:
- true, if the segment is read-only.
- See Also:
asReadOnly()
-
close
void close()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 withIllegalStateException
. Depending on the kind of memory segment being closed, calling this method further trigger deallocation of all the resources associated with the memory segment.- Specified by:
close
in interfaceAutoCloseable
- 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 (seeacquire()
).
-
asByteBuffer
ByteBuffer asByteBuffer()Wraps this segment in aByteBuffer
. Some of the properties of the returned buffer are linked to the properties of this segment. For instance, if this segment is immutable (seeasReadOnly()
, then the resulting buffer is read-only (seeBuffer.isReadOnly()
. Additionally, if this is a native memory segment, the resulting buffer is direct (seeByteBuffer.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 anIllegalStateException
.The resulting buffer's byte order is
ByteOrder.BIG_ENDIAN
; this can be changed usingByteBuffer.order(java.nio.ByteOrder)
.- Returns:
- a
ByteBuffer
view of this memory segment. - Throws:
UnsupportedOperationException
- if this segment cannot be mapped onto aByteBuffer
instance, e.g. because it models an heap-based segment that is not based on abyte[]
), or if its size is greater thanInteger.MAX_VALUE
.IllegalStateException
- if this segment has been closed, or if access occurs from a thread other than the thread owning this segment.
-
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's contents cannot be copied into abyte
instance, e.g. its size is greater thanInteger.MAX_VALUE
.IllegalStateException
- if this segment has been closed, or if access occurs from a thread other than the thread owning this segment.
-
ofByteBuffer
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.
- Parameters:
bb
- the byte buffer backing the buffer memory segment.- Returns:
- a new buffer memory segment.
-
ofArray
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.
- Parameters:
arr
- the primitive array backing the array memory segment.- Returns:
- a new array memory segment.
-
ofArray
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.
- Parameters:
arr
- the primitive array backing the array memory segment.- Returns:
- a new array memory segment.
-
ofArray
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.
- Parameters:
arr
- the primitive array backing the array memory segment.- Returns:
- a new array memory segment.
-
ofArray
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.
- Parameters:
arr
- the primitive array backing the array memory segment.- Returns:
- a new array memory segment.
-
ofArray
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.
- Parameters:
arr
- the primitive array backing the array memory segment.- Returns:
- a new array memory segment.
-
ofArray
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.
- Parameters:
arr
- the primitive array backing the array memory segment.- Returns:
- a new array memory segment.
-
ofArray
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.
- Parameters:
arr
- the primitive array backing the array memory segment.- Returns:
- a new array memory segment.
-
allocateNative
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
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
- ifbytesSize < 0
.
-
mapFromPath
static MemorySegment mapFromPath(Path path, long bytesSize, FileChannel.MapMode mapMode) throws IOExceptionCreates a new mapped memory segment that models a memory-mapped region of a file from a given path.- 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.bytesSize
- the size (in bytes) of the mapped memory backing the memory segment.mapMode
- a file mapping mode, seeFileChannel.map(FileChannel.MapMode, long, long)
.- Returns:
- a new mapped memory segment.
- Throws:
IllegalArgumentException
- ifbytesSize < 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
Creates a new native memory segment that models a newly allocated block of off-heap memory with given size and alignment constraint (in bytes).- 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
- ifbytesSize < 0
,alignmentBytes < 0
, or ifalignmentBytes
is not a power of 2.
-