Interface Arena
- All Superinterfaces:
AutoCloseable,SegmentAllocator
An arena has ascope - thearena 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 berestricted to specific threads. An arena is aSegmentAllocator and features several allocation methods that can be used by clients to obtain native segments.
The simplest arena is theglobal arena. The global arena features anunbounded lifetime. The scope of the global arena is the global scope. 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 beaccessed from any thread.
MemorySegment segment = Arena.global().allocate(100, 1); ... // segment is never deallocated!Alternatively, clients can obtain anautomatic arena, that is an arena which features abounded lifetime that is managed, automatically, by the garbage collector. The scope of an automatic arena is an automatic scope. As such, the regions of memory backing memory segments allocated with the automatic arena are deallocated at some unspecified timeafter the automatic arena (and all the segments allocated by it) becomesunreachable, as shown below:
MemorySegment segment = Arena.ofAuto().allocate(100, 1); ... segment = null; // the segment region becomes available for deallocation after this pointRather 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, namelyconfined andshared arenas. They both feature bounded lifetimes that are managed manually. For instance, when a confined arena isclosed successfully, its scope isinvalidated. As a result, all the memory segments allocated by the arena can no longer be accessed, and their regions of memory are deallocated:
MemorySegment segment = null; try (Arena arena = Arena.ofConfined()) { segment = arena.allocate(100); ... } // segment region deallocated here segment.get(ValueLayout.JAVA_BYTE, 0); // throws IllegalStateExceptionThe characteristics of the various arenas are summarized in the following table:
Arenas characteristics 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
Safety and thread-confinement
Arenas provide strong temporal safety guarantees: a memory segment allocated by an arena cannot be accessedafter the arena has been closed. The cost of providing this guarantee varies based on the number of threads that have access to the memory segments allocated by the arena. For instance, if an arena is always created and closed by one thread, and the memory segments allocated by the arena are always accessed by that same thread, then ensuring correctness is trivial.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 accessedwhile 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 intothread-confined arenas, andshared arenas.
Confined arenas, support strong thread-confinement guarantees. Upon creation, they are assigned anowner thread, typically the thread which initiated the creation operation. The segments created by a confined arena can only beaccessed by the owner thread. Moreover, any attempt to close the confined arena from a thread other than the owner thread will fail with aWrongThreadException.
Shared arenas, on the other hand, have no owner thread. The segments created by a shared arena can beaccessed 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.
Custom arenas
Clients can define custom arenas to implement more efficient allocation strategies, or to have better control over when (and by whom) an arena can be closed. As an example, the following code defines aslicing arena that behaves like a confined arena (i.e., single-threaded access), but internally uses aslicing allocator to respond to allocation requests. When the slicing arena is closed, the underlying confined arena is also closed; this will invalidate all segments allocated with the slicing arena (since the scope of the slicing arena is the same as that of the underlying confined arena):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.allocateFrom(JAVA_INT, 1, 2, 3, 4, 5); ... }} // all memory allocated is released here- Implementation Requirements:
- Implementations of this interface are thread-safe.
- Since:
- 22
- See Also:
Method Summary
Modifier and TypeMethodDescriptionallocate(long byteSize, long byteAlignment) Returns a native memory segment with the given size (in bytes) and alignmentconstraint (in bytes).voidclose()Closes this arena.staticArenaglobal()Returns the global arena.staticArenaofAuto()Creates a new arena that is managed, automatically, by the garbage collector.staticArenaReturns a new confined arena.staticArenaofShared()Returns a new shared arena.scope()Returns the arena scope.Methods declared in interface SegmentAllocator
allocate,allocate,allocate,allocateFrom,allocateFrom,allocateFrom,allocateFrom,allocateFrom,allocateFrom,allocateFrom,allocateFrom,allocateFrom,allocateFrom,allocateFrom,allocateFrom,allocateFrom,allocateFrom,allocateFrom,allocateFrom,allocateFrom,allocateFrom
Method Details
ofAuto
Creates a new arena that is managed, automatically, by the garbage collector.Segments allocated with the returned arena can beaccessed by any thread.Callingclose()on the returned arena will result in anUnsupportedOperationException.Memory segmentsallocated by the returned arenaare zero-initialized.
- Returns:
- a new arena that is managed, automatically, by the garbage collector
global
Returns the global arena. Segments allocated with the global arena can beaccessed by any thread. Callingclose()on the returned arena will result in anUnsupportedOperationException.Memory segmentsallocated by the returned arenaare zero-initialized.
- Returns:
- the global arena
ofConfined
ofShared
allocate
Returns a native memory segment with the given size (in bytes) and alignmentconstraint (in bytes).The returned segment is associated with thisarena scope.The segment'saddressis the starting address ofthe allocated off-heap region of memory backing the segment, and the address isaligned according the provided alignment constraint.- Specified by:
allocatein interfaceSegmentAllocator- Implementation Requirements:
- Implementations of this method must return a native segment featuring therequested size, and that is compatible with the provided alignment constraint.Furthermore, for any two segments
S1, S2returned by this method, thefollowing invariant must hold:S1.asOverlappingSlice(S2).isEmpty() == true - Parameters:
byteSize- the size (in bytes) of the off-heap region of memory backing the native memory segmentbyteAlignment- the alignment constraint (in bytes) of the off-heap region of memory backing the native memory segment- Returns:
- a new native memory segment
- Throws:
IllegalArgumentException- ifbytesSize < 0,byteAlignment <= 0, or ifbyteAlignmentis not a power of 2IllegalStateException- if this arena has already beenclosedWrongThreadException- if this arena is confined, and this method is called from a thread other than the arena's owner thread
scope
close
void close()Closes this arena. If this method completes normally, the arena scope is no longeralive, and all the memory segments associated with itcan no longer be accessed. Furthermore, any off-heap region of memory backing thesegments obtained from this arena are also released.- Specified by:
closein interfaceAutoCloseable- API Note:
- This operation is not idempotent; that is, closing an already closed arenaalways results in an exception being thrown. This reflects a deliberate design choice: failure to close an arena might reveal a bug in the underlying application logic.
- Implementation Requirements:
- If this method completes normally, then
this.scope().isAlive() == false. Implementations are allowed to throwUnsupportedOperationExceptionif an explicit close operation is not supported. - Throws:
IllegalStateException- if the arena has already been closedIllegalStateException- if a segment associated with this arena is being accessed concurrently, e.g. by adowncall method handleRESTRICTEDWrongThreadException- if this arena is confined, and this method is called from a thread other than the arena's owner threadUnsupportedOperationException- if this arena cannot be closed explicitlyRuntimeException- if an exception is thrown while executing a custom cleanup action associated with this arena (e.g. as a result of callingMemorySegment.reinterpret(long, Arena, Consumer)RESTRICTED orMemorySegment.reinterpret(Arena, Consumer)RESTRICTED).- See Also: