ファイルのメモリマッピング
MemorySegmentを使って2GBを超えるファイルを確定的なクリーンアップでマップする。
コード比較
✕ Java 8
try (FileChannel channel =
FileChannel.open(path,
StandardOpenOption.READ,
StandardOpenOption.WRITE)) {
MappedByteBuffer buffer =
channel.map(
FileChannel.MapMode.READ_WRITE,
0, (int) channel.size());
// Limited to 2GB
// Freed by GC, no control
}
✓ Java 22+
FileChannel channel =
FileChannel.open(path,
StandardOpenOption.READ,
StandardOpenOption.WRITE);
try (Arena arena = Arena.ofShared()) {
MemorySegment segment =
channel.map(
FileChannel.MapMode.READ_WRITE,
0, channel.size(), arena);
// No size limit
// ...
} // Deterministic cleanup
このコードに問題がありますか? お知らせください。
モダンな方法が優れている理由
サイズ制限なし
回避策なしに2GBを超えるファイルをマップできます。
確定的なクリーンアップ
ArenaはGCのタイミングではなく、スコープ終了時にメモリを解放します。
高いパフォーマンス
モダンなメモリモデルとハードウェアに適合しています。
旧来のアプローチ
MappedByteBuffer
モダンなアプローチ
MemorySegmentとArena
JDKバージョン
22
難易度
上級
JDKサポート
ファイルのメモリマッピング
利用可能
JDK 22(2024年3月)以降、利用可能
仕組み
Foreign Function & Memory API(JEP 454)はMemorySegmentを導入し、安全で効率的なメモリアクセスを実現します。MappedByteBufferとは異なり、MemorySegmentは2GB(Integer.MAX_VALUE)を超えるファイルをサポートし、Arenaを通じた確定的なクリーンアップを提供し、モダンなハードウェアでより優れたパフォーマンスを発揮します。
関連ドキュメント