Module java.base

Interface Arena

All Superinterfaces:
AutoCloseable, SegmentAllocatorPREVIEW

public interface Arena extends SegmentAllocatorPREVIEW, AutoCloseable
Arena is a preview API of the Java platform.
Programs can only use Arena when preview features are enabled.
Preview features may be removed in a future release, or upgraded to permanent features of the Java platform.
An arena controls the lifecycle of memory segments, providing both flexible allocation and timely deallocation.

An arena has a scope, called the arena scope. When the arena is closed, the arena scope is no longer alivePREVIEW. As a result, all the segments associated with the arena scope are invalidated, safely and atomically, their backing memory regions are deallocated (where applicable) and can no longer be accessed after the arena is closed:

 try (Arena arena = Arena.openConfined()) {
     MemorySegment segment = MemorySegment.allocateNative(100, arena.scope());
     ...
 } // memory released here
Furthermore, an arena is a SegmentAllocatorPREVIEW. All the segments allocated by the arena are associated with the arena scope. This makes arenas extremely useful when interacting with foreign code, as shown below:
 try (Arena arena = Arena.openConfined()) {
     MemorySegment nativeArray = arena.allocateArray(ValueLayout.JAVA_INT, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
     MemorySegment nativeString = arena.allocateUtf8String("Hello!");
     MemorySegment upcallStub = linker.upcallStub(handle, desc, arena.scope());
     ...
 } // memory released here

Safety and thread-confinement

Arenas provide strong temporal safety guarantees: a memory segment allocated by an arena cannot be accessed after 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 associated with the arena's scope 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 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.

Since:
20
  • Method Details

    • allocate

      default MemorySegmentPREVIEW allocate(long byteSize, long byteAlignment)
      Returns a native memory segment with the given size (in bytes) and alignment constraint (in bytes). The returned segment is associated with the arena scope. The segment's addressPREVIEW is the starting address of the allocated off-heap memory region backing the segment, and the address is aligned according the provided alignment constraint.
      Specified by:
      allocate in interface SegmentAllocatorPREVIEW
      Implementation Requirements:
      The default implementation of this method is equivalent to the following code:
       MemorySegment.allocateNative(bytesSize, byteAlignment, scope());
      
      More generally implementations of this method must return a native segment featuring the requested size, and that is compatible with the provided alignment constraint. Furthermore, for any two segments S1, S2 returned by this method, the following invariant must hold:
       S1.overlappingSlice(S2).isEmpty() == true
      
      Parameters:
      byteSize - the size (in bytes) of the off-heap memory block backing the native memory segment.
      byteAlignment - 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 - if bytesSize < 0, alignmentBytes <= 0, or if alignmentBytes is not a power of 2.
      IllegalStateException - if the arena has already been closed.
      WrongThreadException - if this method is called from a thread T, such that scope().isAccessibleBy(T) == false.
      See Also:
    • scope

      Returns the arena scope.
      Returns:
      the arena scope
    • close

      void close()
      Closes this arena. If this method completes normally, the arena scope is no longer alivePREVIEW, and all the memory segments associated with it can no longer be accessed. Furthermore, any off-heap region of memory backing the segments associated with that scope are also released.
      Specified by:
      close in interface AutoCloseable
      API Note:
      This operation is not idempotent; that is, closing an already closed arena always 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.
      Throws:
      IllegalStateException - if the arena has already been closed.
      IllegalStateException - if the arena scope is kept alivePREVIEW.
      WrongThreadException - if this method is called from a thread T, such that isCloseableBy(T) == false.
      See Also:
    • isCloseableBy

      boolean isCloseableBy(Thread thread)
      Returns true if the provided thread can close this arena.
      Parameters:
      thread - the thread to be tested.
      Returns:
      true if the provided thread can close this arena
    • openConfined

      static ArenaPREVIEW openConfined()
      Returns a new confined arena, owned by the current thread.
      Returns:
      a new confined arena, owned by the current thread
    • openShared

      static ArenaPREVIEW openShared()
      Returns a new shared arena.
      Returns:
      a new shared arena