- JDK 23 用 GraalVM (最新)
- JDK 24 用 GraalVM (早期アクセス)
- JDK 21 用 GraalVM
- JDK 17 用 GraalVM
- アーカイブ
- 開発ビルド
Native Imageでのネイティブメモリ追跡 (NMT)
ネイティブメモリ追跡(NMT)は、アプリケーションのオフヒープメモリ使用量を記録するサービス機能です。「オフヒープメモリ」という用語は、「ネイティブメモリ」または「非管理メモリ」と互換性がある場合に使用されることがあります。これは基本的に、ガベージコレクタによって管理されないメモリを意味します。
HotSpot JVMとは異なり、Native Imageは主にガベージコレクタによって管理される収集されたヒープ上のメモリを使用します。ただし、管理されたヒープでの割り当てを避けるために、Native Imageによってネイティブメモリが使用される場所はまだ多くあります。例としては、JFR、ガベージコレクタ、およびヒープダンプなどがあります。ネイティブメモリは、`Unsafe#allocateMemory(long)`を使用してアプリケーションレベルで直接要求することもできます。
ネイティブメモリ追跡の有効化 #
NMTサポートはデフォルトで無効になっており、ビルド時に明示的に有効にする必要があります。
NMTでネイティブ実行可能ファイルをビルドするには、`--enable-monitoring=nmt`オプションを使用します。NMTがビルド時に含まれている場合、実行時には常に有効になります。これは、実行時にNMTの有効/無効を切り替えることができるHotSpotとは異なります。
native-image --enable-monitoring=nmt YourApplication
ネイティブ実行可能ファイルからアプリケーションを起動するときに `-XX:+PrintNMTStatistics` を追加すると、NMTはアプリケーションが完了したときに標準出力にレポートを書き出すように指示します。
./yourapplication -XX:+PrintNMTStatistics
パフォーマンス #
Native Imageでは、NMTのCPUとメモリ消費量の両方が非常に最小限です。JFRなどの他のサービス機能と比較して、NMTのオーバーヘッドは比較的非常にわずかです。
NMTのJFRイベント #
OpenJDK JFRイベントの `jdk.NativeMemoryUsage` と `jdk.NativeMemoryUsageTotal` は、Native Imageでサポートされています。
アクセスできるNative Image固有のJFRイベントが2つあります: `jdk.NativeMemoryUsagePeak` と `jdk.NativeMemoryUsageTotalPeak`。これらのNative Image固有のイベントは、OpenJDKから移植されたJFRイベントでは公開されないピーク使用量データを公開するために作成されました。これらの新しいイベントは実験的としてマークされています。JDK Mission Controlなどのソフトウェアで表示するには、実験的イベントを有効にする必要がある場合があります。
これらのJFRイベントをNMTに使用するには、`native-image`ツールを呼び出すときに`--enable-monitoring=jfr,nmt`オプションを渡してJFR監視を有効にし、実行時にJFR記録を開始します。(詳細については、Native ImageでのJDK Flight Recorder(JFR) を参照してください)。
新しいイベントが `jfr` コマンドラインツールを使用して表示された場合の例を以下に示します
jfr print --events jdk.NativeMemoryUsagePeak recording.jfr
jdk.NativeMemoryUsagePeak {
startTime = 13:18:50.605 (2024-04-30)
type = "Threading"
peakReserved = 424 bytes
peakCommitted = 424 bytes
countAtPeak = 4
eventThread = "JFR Shutdown Hook" (javaThreadId = 63)
}
jdk.NativeMemoryUsagePeak {
startTime = 13:18:50.605 (2024-04-30)
type = "Unsafe"
peakReserved = 14.0 kB
peakCommitted = 14.0 kB
countAtPeak = 2
eventThread = "JFR Shutdown Hook" (javaThreadId = 63)
}
制限事項 #
HotSpotでは、NMTにはサマリーモードと詳細モードの2つのモードがあります。Native Imageでは、現在NMTサマリーモードのみがサポートされています。コールサイト追跡を有効にする詳細モードは利用できません。ベースラインのキャプチャもまだできません。これらの追加機能のサポートに関心がある場合は、GitHubのGraalVMプロジェクトにリクエストを提出してください。
(JDK 23用GraalVMの時点で)現在利用可能な機能は、malloc追跡のみです。
HotSpotと同様に、Native ImageはVMレベルでの割り当てと`Unsafe#allocateMemory(long)`で行われた割り当てのみを追跡できます。たとえば、ライブラリコードまたはアプリケーションコードがmallocを直接呼び出すと、その呼び出しはNMTアカウンティングをバイパスして追跡されません。