
2026/05/12 4:33
Java のレコードをネイティブメモリに高速でマップするためのライブラリ
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
TypedMemory は、Foreign Function & Memory (FFM) API に基づいて構築された、実験的で高パフォーマンスの Java ライブラリであり、強力に型付けされた非ヒープメモリへのアクセスを簡素化します。本ライブラリは ClassFile API を使用しているため、Java 25 以降の使用を対象としており、ネイティブアクセスを有効にするために特定の JVM フラグ(例:
--enable-native-access)の設定が必要です。本ライブラリでは Mem.of() を用いて Java レコードを物理メモリに直接マッピングし、get、set、fill、copyTo、swap などの操作をサポートします。また、型付けされたメモリアロケーション、レコードレイアウトの導出、メモリエイアウトに関する内省、既存のセグメントへのラッパー機能、アノテーションによる固定サイズ配列表場などの機能を備えています。
本 API はグラフィックパイプライン、シミュレーションシステム、ネイティブ連携層、バイナリプロトコルにおけるコードを大幅に削減しますが、以下の制限点にはユーザーが留意する必要があります:レコード内部は変長データのためにヒープアロケートされた配列に依存しており、ゼロコピー動作を必要とする厳密な非ヒープシナリオではパフォーマンスに影響を与える可能性があります。また、ユニオン型はまだサポートされていません。コア API は現在 Apache License 2.0 に基づいて実験的であり、新機能(単純な長整数アドレスを超えたポインタ型フィールドなど)の追加に伴い設計が変化し、互換性を損なう変更が生じる可能性があります。本ライブラリは Maven Central で
io.github.mambastudio:typedmemory:v0.1.0 として入手可能です。本文
Java 25 以降のための Typed off-heap メモリ
TypedMemory は、強引きな型のビューを通じて連続したオフヒープメモリを操作するための Java ライブラリです。Java Foreign Function & Memory(FFM)API の機能を拡張しており、シンプルで表現力の高い API を通じて、Java レコード型をネイティブメモリにマッピングすることを可能にします。各構造体のレイアウト、オフセット、および低レベルなアクセスパターンを手動で管理する必要がないようにするため、TypedMemory は型安全性の保証されたメモリアブストラクションを提供すると同時に、システム開発、相互運用性、グラフィックス、シミュレーション、データ指向プログラミングといった用途において不可欠な低レベル制御も維持します。
import module com.mamba.typedmemory; record Point(float x, float y) {} void main() { try (Arena arena = Arena.ofConfined()) { Mem<Point> points = Mem.of(Point.class, arena, 10); points.set(0, new Point(5, 3)); Point point = points.get(0); IO.println(point); } }
なぜ TypedMemory か?
Java で生メモリのデータを直接扱うことは強力ですが、往々にして冗長で反復的な作業を招きます。TypedMemory は、以下を提供することでオフヒーププログラミングをより直感的なものにすることを目指しています:
- 連続したメモリへの強引きな型によるビュー
- 構造化データを記述するためのレコードベースのスキーマ
- 配分の制御と寿命管理への明示的なアプローチ
- ネイティブ相互運用性のために低レベルなレイアウトを保持する
- 高速な初期化とコピーのためのバッチ操作
- メモリ概念を完全に隠蔽することなく、FFM モデルに近い設計 philosophy を採用している
これにより、以下のような用途に役立ちます:
- ネイティブ相互運用性(Native Interop)
- データ指向プログラミング
- ハイパフォーマンスなメモリレイアウト
- シミュレーションおよびゲーム・グラフィックスワークロード
- オフヒープに格納される大規模な構造化データセット
機能特性
- Java レコード型を連続したオフヒープメモリへマッピング
を使用してメモリの配分を行うArena- インデックス指定で要素を読み書き(
/get(index)
)set(index, value) - 生成された
を点検可能MemoryLayout - 既存の
をラップするMemorySegment - 与えられたサイズまたはアドレスにおいてメモリの解釈を再定義する
- メモリ領域への書き込み、初期化、交換、コピー操作をサポート
- ネストされた構造化データのサポート
- 固定長アレイフィールドのサポート
ステータス
TypedMemory は現在実験段階にあります。コア API はすでに利用可能ですが高品質な設計へ向けてプロジェクトは発展途上であり、デザインが微調整される過程で破壊的な変更が入る可能性があります。
現状の実装状況
- typed メモリの配分機能
- レコードレイアウトの自動導出機能
- typed の get/set アクセス機能
- 既存セグメントのラッピング機能
- 再解釈化(reinterpretation)サポート
- 基本的なバッチ操作
今後の計画 実装予定の機能:
アドレスを手動で扱うことを超えたポインタ型のフィールドlong- ユニオン型
要件
クラスファイル API の関係上、Java 25 以上のバージョンが必要です。
また、再解釈化(reinterpret)の呼び出しでは、アプリケーション側で特定のコマンドフラグを有効にする必要があります:
- JAR ファイルの場合:
java --enable-native-access=ALL-UNNAMED -jar app.jar - Named module の場合:
java --enable-native-access=your.module.name -m your.module.name/com.example.Main
ビルド方法
TypedMemory は Maven を使用してビルドされ、ターゲットは Java 25 です。
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.release>25</maven.compiler.release> </properties> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.2.5</version> </plugin> </plugins> </build>
ライブラリのコンパイル: テストの実行: JAR の構築: ローカルの Maven リポジトリへ TypedMemory のインストール:
Maven プロジェクトでの利用方法 / 導入
TypedMemory は Maven Central から入手可能ですので、プロジェクトの
pom.xml に直接追加できます:
<dependency> <groupId>io.github.mambastudio</groupId> <artifactId>typedmemory</artifactId> <version>0.1.0</version> </dependency>
アプリケーションが Java モジュールシステムを使用する場合は、
module-info.java に以下の記述を追加してください:
requires com.mamba.typedmemory;
シンプルな例
import module com.mamba.typedmemory; record Color(float r, float g, float b, float a) { Color(float r, float g, float b) { this(r, g, b, 1.0f); } } void main(){ try (Arena arena = Arena.ofConfined()) { Mem<Color> colors = Mem.of(Color.class, arena, 3); colors.set(0, new Color(1f, 0f, 0f)); colors.set(1, new Color(0f, 1f, 0f)); colors.set(2, new Color(0f, 0f, 1f)); Color c = colors.get(1); IO.println(c); // 出力例:Color[r=0.0, g=1.0, b=0.0, a=1.0] } }
構造化レコードを使用した例
import module com.mamba.typedmemory; record Pixel(int i, int j) {} record Point(byte x, @size(3) Pixel[] y, @size(3) int[] z) {} void main(){ try (Arena arena = Arena.ofConfined()) { Mem<Point> points = Mem.of(Point.class, arena, 10); points.set(0, new Point( (byte) 7, new Pixel[] { new Pixel(1, 2), new Pixel(3, 4), new Pixel(5, 6) }, new int[] { 10, 20, 30 } )); Point p = points.get(0); IO.println(p); } }
レイアウトのintrospection
TypedMemory は、実際オフヒープに保存される構造体を点検し、その本質的なレイアウトを保持します。これにより以下の場面での作業が容易になります:
- ネイティブ相互運用性のレイアウト検証
- 配置(alignment)およびパディングの確認
- オフヒープ構造化データのデバッグ
既存メモリのラッピング
TypedMemory は、既存の
MemorySegment を通じて typed なビューを作成することもできます。
MemorySegment segment = ...; Mem<Color> colors = Mem.wrap(Color.class, segment);
これは以下の状況において特に有用です:
- ネイティブライブラリからのメモリ取得時
- 外部アロケーターを利用している場合
- 既存の FFM ワークフローからメモリを再利用する場合
コア API
典型的な操作には以下が含まれます:
Mem<T> mem = Mem.of(MyRecord.class, arena, count); mem.get(index); mem.set(index, value); mem.fill(value); mem.init(i -> ...); mem.copyTo(other); mem.copyFrom(other); mem.swap(i, j); mem.segment(); mem.layout(); mem.size(); mem.type();
設計理念
TypedMemory は FFM API を置換することを意図していません。むしろ、FFM API の上層に位置取り:
- メモリの明示性を維持する
- レイアウトの意味性を保つ
- 冗長なコード(boilerplate)を削減する
- 構造化されたオフヒープデータの可読性を向上させる
目的は、低レベルの Java メモリプログラミングを typed であると感じ、かつ直接的で実践的なものとして体験できるようにすることです。
なぜレコードを使用するか?
レコードは、構造化メモリに対して自然なスキーマ様のモデルを提供します。これらは以下の特徴を持ちます:
- 明示的な状態記述
- 安定したコンポーネント順序付け
- コンサイスなシンタックス
- 自動生成されたレイアウト/アクセスコードへの強い適合性
TypedMemory は、この特徴を活用して Java のデータ定義と低レベルメモリアブストラクトを橋渡しします。
ベンチマーク結果
今後のリリースにて公開予定。
使用ケース
TypedMemory は以下の分野に特に関連性が高いと言えます:
- グラフィックスおよびレンダリングパイプライン
- シミュレーションシステム
- ネイティブ相互運用性レイヤー
- バイナリプロトコル構造体
- ハイパフォーマンスなデータコンテナ
- 実験的なデータ指向 Java プログラミング
プロジェクトの目標
- Java における構造化オフヒープメモリの使用を容易化すること
- レイアウトレベルでの思考モデルとネイティブ互換性を維持すること
- コントロールを犠牲にせず、クリーンな API を提供すること
- モダンな Java が低レベルプログラミングにおいてどこまで到達できるかを探求すること
制限事項
以下の点が現状の制限となります:
- Java 25 以上が必要です。
- ユニオン型はまだ実装されていません(実現方法へのアイデアはありますか?)。
- スキーマのすべての形状がまだサポートされているわけではありません(キャリアークラスの開発進展を見守りたいと思います)。
- Java のアレイは主にヒープ上に配分されるため、レコード内のフィールドとして使用した場合、パフォーマンスに影響する可能性があります。
コントリビュート
フィードバック、バグ報告、提案を歓迎いたします。以下に興味をお持ちの皆さまからのコントリビュートと議論を特に歓迎いたします:
- Java FFM
- オフヒープデータ構造体
- データ指向プログラミング
- ネイティブ相互運用性
- 低レベル Java パフォーマンス
リポジトリ
GitHub:
mamba-studio/TypedMemory
ライセンス
TypedMemory は Apache License 2.0 の下でライセンスされています。