1. 概要

このクイックチュートリアルでは、実行中のJavaアプリケーションのヒープサイズを取得するためのいくつかの異なる方法を理解します。

2. jcmd

実行中のJavaアプリケーションのヒープおよびメタスペース関連の情報を見つけるには、jcmdコマンドラインユーティリティを使用できます。

jcmd  GC.heap_info

まず、 jps コマンドを使用して、特定のJavaアプリケーションのプロセスIDを見つけましょう。

$ jps -l
73170 org.jetbrains.idea.maven.server.RemoteMavenServer36
4309  quarkus.jar
12070 sun.tools.jps.Jps

上に示したように、QuarkusアプリケーションのプロセスIDは4309です。 プロセスIDがわかったので、ヒープ情報を見てみましょう。

$ jcmd 4309 GC.heap_info
4309:
 garbage-first heap   total 206848K, used 43061K
  region size 1024K, 43 young (44032K), 3 survivors (3072K)
 Metaspace       used 12983K, capacity 13724K, committed 13824K, reserved 1060864K
  class space    used 1599K, capacity 1740K, committed 1792K, reserved 1048576K

このアプリは、G1またはガベージファーストGCアルゴリズムを使用しています。

  • 最初の行は、現在のヒープサイズを202 MB(206848 K)として報告します。また、42 MB(43061 K)が使用されています
  • G1リージョンは1MBで、43のリージョンが若いとマークされ、3つのリージョンがサバイバースペースとしてマークされています。
  • メタスペースの現在の容量は約13.5MB(13724 K)です。 その13.5MBから、約12.5 MB(12983 K)が使用されます。 また、最大1 GBのメタスペース(1048576 K)を使用できます。 さらに、コミットされたメモリとしても知られるJava仮想マシンでの使用が保証された13842 KB
  • 最後の行は、クラス情報を格納するために使用されるメタスペースの量を示しています

この出力は、GCアルゴリズムによって変わる可能性があります。 たとえば、 “-XX:+ UnlockExperimentalVMOptions -XX:+ UseZGC”を介してZGCで同じQuarkusアプリを実行すると、次のようになります。

ZHeap           used 28M, capacity 200M, max capacity 1024M
Metaspace       used 21031K, capacity 21241K, committed 21504K, reserved 22528K

上に示したように、28MBのヒープと約20MBのメタスペースを使用しています。 この記事を書いている時点で、IntellijIDEAはまだ次のヒープ情報を持つCMSGCを使用しています。

par new generation   total 613440K, used 114299K
  eden space 545344K,  18% used
  from space 68096K,  16% used
  to   space 68096K,   0% used
 concurrent mark-sweep generation total 1415616K, used 213479K
 Metaspace       used 423107K, capacity 439976K, committed 440416K, reserved 1429504K
  class space    used 55889K, capacity 62488K, committed 62616K, reserved 1048576K

ヒープ構成でCMSGCの古典的な世代の性質を見つけることができます。

3. jstat

jcmd に加えて、 jstat を使用して、実行中のアプリケーションから同じ情報を見つけることができます。 たとえば、 jstat -gc を使用して、ヒープ統計を表示できます。

$ jstat -gc 4309
S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     
0.0    0.0    0.0    0.0   129024.0  5120.0   75776.0    10134.6   20864.0
MU      CCSC   CCSU     YGC     YGCT    FGC    FGCT     CGC    CGCT     GCTGCT
19946.2 2688.0 2355.0    2      0.007    1      0.020    0     0.000     0.027

各列は、特定のメモリ領域のメモリ容量または使用率を表します。

  • S0C —最初のサバイバースペースの容量
  • S1C —2番目のサバイバースペースの容量
  • S0U —最初の生存者の使用済みスペース
  • S1U —2番目の生存者の使用済みスペース
  • EC —エデンスペース容量
  • EU —エデンの使用済みスペース
  • OC —旧世代の容量
  • OU —旧世代の使用済みスペース
  • MC —メタスペース容量
  • MU —メタスペースの使用済みスペース
  • CCSC —圧縮されたクラススペース容量
  • CCSU —圧縮されたクラスに使用されるスペース
  • YGC —マイナーGCの数
  • YGCT —マイナーGCに費やされた時間
  • FGC —完全なGCの数
  • FGCT —完全なGCに費やされた時間
  • CGC —同時GCの数
  • CGCT —同時GCに費やされた時間
  • GCT —すべてのGCに費やされた時間

jstat には、次のような他のメモリ関連のオプションがあります。

  • -gccapacity は、さまざまなメモリ領域のさまざまな容量を報告します
  • -gcutil は、各リージョンの使用率のみを表示します
  • -gccause-gcutilと同じですが、最後のGCおよび場合によっては現在のGCイベントの原因を追加します

4. コマンドライン引数

ヒープ構成オプション(たとえば、-Xmsおよび-Xmx)を使用してJavaアプリケーションを実行する場合、指定された値を見つけるための他のいくつかのトリックがあります。

たとえば、jpsがこれらの値を報告する方法は次のとおりです。

$ jps -lv
4309 quarkus.jar -Xms200m -Xmx1g

このアプローチでは、これらの静的な値しか見つけることができません。 したがって、たとえば、現在コミットされているメモリについて知る方法はありません。

jps に加えて、他のいくつかのツールが同じことを報告します。 たとえば、 「jcmd VM.command_line」 これらの詳細も報告されます:

$ jcmd 4309 VM.command_line
4309:
VM Arguments:
jvm_args: -Xms200m -Xmx1g
java_command: quarkus.jar
java_class_path (initial): quarkus.jar
Launcher Type: SUN_STANDARD

また、ほとんどのUnixベースのシステムでは、procpsパッケージのpsを使用できます。

$ ps -ef | grep quarkus
... java -Xms200m -Xmx1g -jar quarkus.jar

最後に、Linuxでは、 /proc仮想ファイルシステムとそのpidファイルを使用できます。

$ cat /proc/4309/cmdline
java -Xms200m -Xmx1g -jar quarkus.jar

Quarkuspidにちなんで名付けられたディレクトリにあるcmdlineファイルには、アプリケーションのコマンドラインエントリが含まれています。

5. 結論

このクイックチュートリアルでは、実行中のJavaアプリケーションのヒープサイズを取得するためのいくつかの異なる方法を見ました。