AutoCloseable
, SegmentAllocatorPREVIEW
public interface Arena extends SegmentAllocatorPREVIEW, AutoCloseable
Arena
is a preview API of the Java platform. An arena has a scopePREVIEW - the arena scope. All the segments allocated by the arena are associated with the arena scope. As such, the arena determines the temporal bounds of all the memory segments allocated by it.
Moreover, an arena also determines whether access to memory segments allocated by it should be restrictedPREVIEW to specific threads. An arena is a SegmentAllocator
PREVIEW and features several allocation methods that can be used by clients to obtain native segments.
The simplest arena is the global arena. The global arena features an unbounded lifetime. As such, native segments allocated with the global arena are always accessible and their backing regions of memory are never deallocated. Moreover, memory segments allocated with the global arena can be accessedPREVIEW from any thread.
MemorySegment segment = Arena.global().allocate(100, 1);
...
// segment is never deallocated!
Alternatively, clients can obtain an automatic arena, that is an arena which features a bounded lifetime that is managed, automatically, by the garbage collector. As such, the regions of memory backing memory segments allocated with the automatic arena are deallocated at some unspecified time after the automatic arena (and all the segments allocated by it) becomes unreachable, as shown below:
MemorySegment segment = Arena.ofAuto().allocate(100, 1);
...
segment = null; // the segment region becomes available for deallocation after this point
Rather than leaving deallocation in the hands of the Java runtime, clients will often wish to exercise control over the timing of deallocation for regions of memory that back memory segments. Two kinds of arenas support this, namely confined and shared arenas. They both feature bounded lifetimes that are managed manually. For instance, the lifetime of a confined arena starts when the confined arena is created, and ends when the confined arena is closed. As a result, the regions of memory backing memory segments allocated with a confined arena are deallocated when the confined arena is closed. When this happens, all the segments allocated with the confined arena are invalidated, and subsequent access operations on these segments will fail IllegalStateException
:
MemorySegment segment = null;
try (Arena arena = Arena.ofConfined()) {
segment = arena.allocate(100);
...
} // segment region deallocated here
segment.get(ValueLayout.JAVA_BYTE, 0); // throws IllegalStateException
The characteristics of the various arenas are summarized in the following table:
Kind Bounded lifetime Explicitly closeable Accessible from multiple threads Global No No Yes Automatic Yes No Yes Confined Yes Yes No Shared Yes Yes Yes
Conversely, if an arena allocates segments that can be accessed by multiple threads, or if the arena can be closed by a thread other than the accessing thread, then ensuring correctness is much more complex. For example, a segment allocated with the arena might be accessed while another thread attempts, concurrently, to close the arena. To provide the strong temporal safety guarantee without forcing every client, even simple ones, to incur a performance impact, arenas are divided into thread-confined arenas, and shared arenas.
Confined arenas, support strong thread-confinement guarantees. Upon creation, they are assigned an owner thread, typically the thread which initiated the creation operation. The segments created by a confined arena can only be accessedPREVIEW by the owner thread. Moreover, any attempt to close the confined arena from a thread other than the owner thread will fail with WrongThreadException
.
Shared arenas, on the other hand, have no owner thread. The segments created by a shared arena can be accessedPREVIEW by any thread. This might be useful when multiple threads need to access the same memory segment concurrently (e.g. in the case of parallel processing). Moreover, a shared arena can be closed by any thread.
class SlicingArena implements Arena {
final Arena arena = Arena.ofConfined();
final SegmentAllocator slicingAllocator;
SlicingArena(long size) {
slicingAllocator = SegmentAllocator.slicingAllocator(arena.allocate(size));
}
public MemorySegment allocate(long byteSize, long byteAlignment) {
return slicingAllocator.allocate(byteSize, byteAlignment);
}
public MemorySegment.Scope scope() {
return arena.scope();
}
public void close() {
arena.close();
}
}
try (Arena slicingArena = new SlicingArena(1000)) {
for (int i = 0; i < 10; i++) {
MemorySegment s = slicingArena.allocateArray(JAVA_INT, 1, 2, 3, 4, 5);
...
}
} // all memory allocated is released here
Modifier and Type | Method | Description |
---|---|---|
default MemorySegmentPREVIEW |
allocate |
Returns a native memory segment with the given size (in bytes) and alignment constraint (in bytes). |
void |
close() |
Closes this arena. |
static ArenaPREVIEW |
global() |
Obtains the global arena. |
static ArenaPREVIEW |
ofAuto() |
Creates a new arena that is managed, automatically, by the garbage collector. |
static ArenaPREVIEW |
ofConfined() |
Returns a new confined arena. |
static ArenaPREVIEW |
ofShared() |
Returns a new shared arena. |
MemorySegment.ScopePREVIEW |
scope() |
Returns the arena scope. |
allocate, allocate, allocate, allocate, allocate, allocate, allocate, allocate, allocate, allocate, allocateArray, allocateArray, allocateArray, allocateArray, allocateArray, allocateArray, allocateArray, allocateArray, allocateUtf8String
static ArenaPREVIEW ofAuto()
close()
on the returned arena will result in an UnsupportedOperationException
.static ArenaPREVIEW global()
close()
on the returned arena will result in an UnsupportedOperationException
.static ArenaPREVIEW ofConfined()
default MemorySegmentPREVIEW allocate(long byteSize, long byteAlignment)
address
PREVIEW is the starting address of the allocated off-heap region of memory backing the segment, and the address is aligned according the provided alignment constraint.allocate
in interface SegmentAllocatorPREVIEW
S1, S2
returned by this method, the following invariant must hold: S1.asOverlappingSlice(S2).isEmpty() == true
byteSize
- the size (in bytes) of the off-heap region of memory backing the native memory segment.byteAlignment
- the alignment constraint (in bytes) of the off-heap region of memory backing the native memory segment.IllegalArgumentException
- if bytesSize < 0
, byteAlignment <= 0
, or if byteAlignment
is not a power of 2.IllegalStateException
- if this arena has already been closed.WrongThreadException
- if this arena is confined, and this method is called from a thread other than the arena's owner thread.MemorySegment.ScopePREVIEW scope()
void close()
close
in interface AutoCloseable
this.scope().isAlive() == false
. Implementations are allowed to throw UnsupportedOperationException
if an explicit close operation is not supported.IllegalStateException
- if the arena has already been closed.IllegalStateException
- if a segment associated with this arena is being accessed concurrently, e.g. by a downcall method handlePREVIEW.WrongThreadException
- if this arena is confined, and this method is called from a thread other than the arena's owner thread.UnsupportedOperationException
- if this arena cannot be closed explicitly.
© 1993, 2023, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/foreign/Arena.html
Arena
when preview features are enabled.