- すべてのスーパー・インタフェース:
AutoCloseable
,SegmentAllocator
アリーナには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
様々なアリーナの特性を次の表にまとめます:
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
- 関連項目:
-
メソッドのサマリー
修飾子と型メソッド説明allocate
(long byteSize, long byteAlignment) 指定されたサイズ(バイト単位)および整列制約(バイト単位)のネイティブ・メモリー・セグメントを返します。void
close()
このアリーナを閉じます。static Arena
global()
グローバル・アリーナを返します。static Arena
ofAuto()
ガベージ・コレクタによって自動的に管理される新しいアリーナを作成します。static Arena
新しい限定されたアリーナを返します。static Arena
ofShared()
新しい共有領域を返します。scope()
arenaスコープを返します。インタフェースjava.lang.foreign.SegmentAllocatorで宣言されたメソッド
allocate, allocate, allocate, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom
-
メソッドの詳細
-
ofAuto
static Arena ofAuto()ガベージ・コレクタによって自動的に管理される新しいアリーナを作成します。 戻されたアリーナで割り当てられるセグメントは、どのスレッドでも「アクセス済」になります。 戻されたアリーナでclose()
をコールすると、UnsupportedOperationException
になります。戻されたアリーナによるメモリー・セグメント「割当済」は、ゼロで初期化されます。
- 戻り値:
- ガベージ・コレクタによって自動的に管理される新しいアリーナ
-
global
static Arena global()グローバル・アリーナを返します。 グローバル・アリーナで割り当てられるセグメントは、どのスレッドでも「アクセス済」にできます。 戻されたアリーナでclose()
をコールすると、UnsupportedOperationException
になります。戻されたアリーナによるメモリー・セグメント「割当済」は、ゼロで初期化されます。
- 戻り値:
- グローバル・アリーナ
-
ofConfined
-
allocate
MemorySegment allocate(long byteSize, long byteAlignment) 指定されたサイズ(バイト単位)および整列制約(バイト単位)のネイティブ・メモリー・セグメントを返します。 返されるセグメントは、この「アリーナ・スコープ」に関連付けられます。 セグメントのaddress
は、セグメントをバッキングするメモリーの割当て済オフ・ヒープ・リージョンの開始アドレスであり、アドレスは指定された整列制約に従って整列されます。- 定義:
- インタフェース
SegmentAllocator
内のallocate
- 実装要件:
- このメソッドの実装は、リクエストされたサイズを持つネイティブ・セグメントを返し、指定された整列制約と互換性がある必要があります。 さらに、このメソッドによって返される2つのセグメント
S1, S2
の場合、次の不変量を保持する必要があります:S1.asOverlappingSlice(S2).isEmpty() == true
- パラメータ:
byteSize
- ネイティブ・メモリー・セグメントをバックアップするメモリーのオフ・ヒープ・リージョンのサイズ(バイト単位)byteAlignment
- ネイティブ・メモリー・セグメントをバックアップするメモリーのオフ・ヒープ・リージョンの整列制約(バイト単位)- 戻り値:
- 新しいネイティブ・メモリー・セグメント
- 例外:
IllegalArgumentException
-bytesSize < 0
、byteAlignment <= 0
、またはbyteAlignment
が2の累乗でない場合IllegalStateException
- このアリーナがすでにclosedである場合WrongThreadException
- このアリーナが限定されていて、このメソッドがアリーナの所有者スレッド以外のスレッドから呼び出された場合
-
scope
-
close
void close()このアリーナを閉じます。 このメソッドが正常に完了すると、アリーナ・スコープはaliveではなくなり、このメソッドに関連付けられているすべてのメモリー・セグメントにアクセスできなくなります。 さらに、このアリーナから取得したセグメントをバッキングするメモリーのオフ・ヒープ・リージョンもすべて解放されます。- 定義:
close
、インタフェースAutoCloseable
- APIのノート:
- この操作はべき等ではありません。つまり、すでに閉じているアリーナalwaysを閉じると、例外がスローされます。 これは意図的な設計の選択を反映しています: アリーナのクローズに失敗すると、基礎となるアプリケーション・ロジックにバグが表示される場合があります。
- 実装要件:
- このメソッドが正常に完了した場合、
this.scope().isAlive() == false
。 明示的なクローズ操作がサポートされていない場合は、実装でUnsupportedOperationException
をスローできます。 - 例外:
IllegalStateException
- アリーナが既に閉鎖されている場合IllegalStateException
- このアリーナに関連付けられたセグメントが同時にアクセスされる場合(downcall method handleRESTRICTEDなど)WrongThreadException
- このアリーナが限定されていて、このメソッドがアリーナの所有者スレッド以外のスレッドから呼び出された場合UnsupportedOperationException
- このアリーナを明示的に閉じられない場合RuntimeException
- このアリーナ(例:MemorySegment.reinterpret(long, Arena, Consumer)
RESTRICTEDまたはMemorySegment.reinterpret(Arena, Consumer)
RESTRICTEDをコールした結果)に関連付けられたカスタム・クリーンアップ・アクションの実行中に例外がスローされた場合。- 関連項目:
-