モジュール java.base
パッケージ java.lang.foreign

インタフェースArena

すべてのスーパー・インタフェース:
AutoCloseable, SegmentAllocator

public interface Arena extends SegmentAllocator, AutoCloseable
アリーナは、ネイティブ・メモリー・セグメントのライフサイクルを制御し、柔軟な割当てとタイムリな割当て解除の両方を提供します。

アリーナにはscopeがあります。 - 「アリーナ・スコープ」 アリーナによって割り当てられたすべてのセグメントは、アリーナ・スコープに関連付けられます。 そのため、アリーナは、割り当てられているすべてのメモリー・セグメントの一時的な範囲を決定します。

さらに、アリーナは、割り当てられたメモリー・セグメントへのアクセスを特定のスレッドに対して「制限付き」にするかどうかも決定します。 アリーナはSegmentAllocatorであり、クライアントがネイティブ・セグメントを取得するために使用できるいくつかの割当てメソッドを備えています。

最も単純なアリーナは、「グローバル・アリーナ」です。 グローバル・アリーナには、「無制限有効期間」があります。 グローバル・アリーナのスコープはグローバル・スコープです。 そのため、グローバル・アリーナに割り当てられたネイティブ・セグメントには常にアクセス可能で、メモリーのバッキング・リージョンは割当て解除されません。 さらに、グローバル・アリーナで割り当てられるメモリー・セグメントは、任意のスレッドから「アクセス済」にすることができます。

 MemorySegment segment = Arena.global().allocate(100, 1);
 ...
 // segment is never deallocated!

あるいは、クライアントは、ガベージ・コレクタによって自動的に管理される「境界有効期間」を特徴とするアリーナである「自動アリーナ」を取得できます。 自動アリーナのスコープは自動スコープです。 そのため、次に示すように、自動アリーナで割り当てられたメモリー・バッキング・メモリー・セグメントのリージョンは、自動アリーナ (およびそれによって割り当てられたすべてのセグメント)がunreachableになったあと、未指定の時間に解放されます:

 MemorySegment segment = Arena.ofAuto().allocate(100, 1);
 ...
 segment = null; // the segment region becomes available for deallocation after this point
自動アリーナで割り当てられたメモリー・セグメントは、任意のスレッドから「アクセス済」にすることもできます。

Javaランタイムの手元に割当て解除を残すのではなく、多くの場合、クライアントはメモリー・セグメントを戻すメモリーのリージョンに対する割当て解除のタイミングを制御することを希望します。 2種類のアリーナ、つまり「限定」およびsharedアリーナがサポートされています。 どちらも、手動で管理される期限付きライフ・タイムを備えています。 たとえば、限定されたアリーナが正常にclosedの場合、そのスコープは「無効」です。 その結果、アリーナによって割り当てられたすべてのメモリー・セグメントにアクセスできなくなり、そのメモリー・リージョンが割当て解除されます。

 MemorySegment segment = null;
 try (Arena arena = Arena.ofConfined()) {
     segment = arena.allocate(100);
     ...
 } // segment region deallocated here
 segment.get(ValueLayout.JAVA_BYTE, 0); // throws IllegalStateException
「限定アリーナ」で割り当てられたメモリー・セグメントには、アリーナを作成したスレッドのみが(クローズ済)にアクセスできます。 複数のスレッドからメモリー・セグメントへのアクセスが必要な場合、クライアントはかわりに「共有アリーナ」内のセグメントを割り当てることができます。

様々なアリーナの特性を次の表にまとめます:

Arenasの特徴
Kind 制限付き存続期間 明示的にクローズ可能 複数のスレッドからアクセス可能
グローバル No No あり
自動 あり No あり
確定済 あり あり No
共有 あり あり あり

安全性とスレッドの制約

Arenasは強力な時間的安全保証を提供: アリーナが割り当てたメモリー・セグメントには、そのアリーナを閉じたあとはアクセスできません。 この保証を提供するコストは、アリーナによって割り当てられたメモリー・セグメントにアクセスできるスレッドの数によって異なります。 たとえば、アリーナが常に1つのスレッドによって作成およびクローズされ、そのアリーナによって割り当てられたメモリー・セグメントに常に同じスレッドからアクセスされる場合は、正確さが微妙であることを確認します。

逆に、アリーナが複数のスレッドからアクセスできるセグメントを割り当てる場合や、アクセスしているスレッド以外のスレッドでアリーナをクローズできる場合は、正確さがはるかに複雑になります。 たとえば、アリーナに割り当てられているセグメントには、whileにもう一度アクセスして、アリーナを閉じようとします。 すべてのクライアント(単純なクライアントでも)パフォーマンスへの影響を発生させることなく、強力な時間的安全保証を提供するために、領域がthread-confined領域およびshared領域に分割されます。

限られた領域で、強力なスレッド制約の保証をサポートします。 作成時に、「所有者スレッド」に割り当てられるのは通常、作成操作を開始したスレッドです。 限定アリーナによって作成されたセグメントは、所有者スレッドによってのみ「アクセス済」になります。 さらに、所有者スレッド以外のスレッドから閉じ込められたアリーナを閉じようとすると、WrongThreadExceptionで失敗します。

一方、共有領域には所有者スレッドがありません。 共有アリーナによって作成されたセグメントは、どのスレッドでも「アクセス済」にできます。 これは、複数のスレッドが同じメモリー・セグメントに同時に(例:パラレル処理の場合)にアクセスする必要がある場合に役立ちます。 また、共有アリーナはどのスレッドでも閉じることができます。

カスタム・アリーナ

クライアントは、より効率的な割当て戦略を実装したり、アリーナをクローズできる(だれが)をより適切に制御するために、カスタム・アリーナを定義できます。 たとえば、次のコードでは、限定アリーナ(つまり、シングル・スレッド・アクセス)のように動作する「スライシング・アリーナ」を定義していますが、内部的には「スライシング・ロケータ」を使用して割当てリクエストに応答します。 スライス・アリーナが閉じられると、基礎となる限定されたアリーナも閉じられます。これにより、スライス・アリーナ(スライス・アリーナの範囲は基礎となる限定されたアリーナの範囲と同じであるため)に割り当てられているすべてのセグメントが無効になります:
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
実装要件:
このインタフェースの実装はスレッド・セーフです。
導入されたバージョン:
22
関連項目: