プログラミング

jstatによるヒープメモリ/GCの確認。Javaのメモリ使用量を分析して性能改善する方法

*記事内に商品プロモーションを含む場合があります

Javaで作成したプログラムのメモリ使用量の調査方法や、性能改善のポイントを紹介します。

WindowsでもLinuxどちらでも使える手法です。

javaプロセスのメモリ使用量の確認方法

JDKに含まれているjpsとjstatを利用します。

jstatを使うには、JDKのインストールが必要です。

jstat は、 Java 仮想マシン統計データ監視ツールです。

jpsでjavaプロセスを確認

まずjpsでJVMが動いているプロセスを特定します。

$

$ jps -h
usage: jps [--help]
     jps [-q] [-mlvV] []

Definitions:
  :    [:]
  -? -h --help -help: Print this help message and exit.
  
$ jps -q
37064
41337

$ jps -m
37064 testProMain --check -u test1/pw01 --opt 2
41387 Jps -m

$ jps -l
41426 sun.tools.jps.Jps
37064 com.test.tool.testProMain
 
$ jps -v
37064 testProMain -Xmx8192

$ jps -V
37064 testProMain
41501 Jps

jstatでJVMのメモリ使用状況を確認

jstat は、 Java 仮想マシン統計データ監視ツールです。

今回調査対象のプロセスIDは37064なので、jstatの次の引数でメモリ状況を確認します。

10秒ごとに採取すればいいでしょう。

jstat  -gc  -t  -h10  <PID>   10000

jstat  -gc  -t  -h10  37064  10000

・-t  :タイムスタンプを付けるオプション
・-h10 :10行ごとにヘッダを1回出力するオプション
・最後の10000は10秒ごとに統計情報を出力するオプション

$

$ top
  PID USER  PR  NI  VIRT  RES  SHR S  %CPU %MEM   TIME+ COMMAND
37064 user1   20   0   12.0g   8.3g  14076 S 205.6  4.4 125:25.04 java

$ jps -v
37064 testProMain -Xmx1024m -Dlogback.configurationFile=./testpro_logback.xml

$ jstat -gc -t -h10  37064  10000
Timestamp     S0C     S1C     S0U     S1U     EC     EU     OC     OU     MC    MU        CCSC  CCSU  YGC    YGCT  FGC     FGCT  GCT
3250.1   1024.0   1024.0   0.0     448.0   2792960.0       1060138.3       5592576.0       5404957.5        13440.0 13169.8 1408.0   1318.0   1209    68.622   37      22.613   91.235
3260.1   1024.0   1024.0   0.0     480.0   2793984.0       812763.8       5592576.0       5404972.6        13440.0 13169.8 1408.0   1318.0   1213    68.695   37      22.613   91.308
3270.1   1024.0   1024.0   0.0     448.0   2793984.0       1672611.3       5592576.0       5405092.6        13440.0 13169.8 1408.0   1318.0   1217    68.772   37      22.613   91.386
 :

★画面だと分析できないので、ファイルに出力します。
TSV(タブ区切り / .tsvファイル)で出力します。

 jstat -gcutil -t 37064 10000 > jstat.tsv

ExcelでTSVファイルを開いて色を付けた画像です。

JVMの使用メモリサイズの解析

jstatコマンドの出力から、実際に使用しているメモリを調査します。

jstatで使用しているメモリを調査

使用メモリの大まかな推移を見るのは、jstatの出力の”O”(OLD領域の使用率)の項目に着目すれば傾向が分かります。

Timestampの数値を横軸、「O(OLD領域の使用率)」の数値を縦軸にしたグラフが以下になります。

■O(OLD領域メモリの使用率)

■FGCT(フルガベージコレクションの時間)
GCの時間が徐々に増えています。後半の処理性能は落ちていると予想。

javaのメモリ使用率を分析

このJavaプログラムはデータベースから数時間かけて、データを取得してファイルに出力するものです。

正常終了しているのですが、メモリの利用状況を見ると動作が怪しそうです。


(a)前半は使用率95%を超えたらGCでメモリ解放を行っている。
FCGの速度低下も少ないので、問題なし。

(b)後半は、常に90%以上の高い使用率で100%近くに張り付いていて、時々GCでメモリ解放している。
また、FGCの時間もどんどん伸びている。(FGCT)

javaのメモリ使用増加の対策例

細かく分析した訳ではないので、あくまでも考え方の例です。

・不要なオブジェクトのクローズ漏れはないか?

・もう少し処理するデータが増えたりするとメモリ不足(outOfmemoryException)など発生しないか?

→ 一括して実行する単位を減らすなど対策が必要。

90%近くの使用量が連続する前まで一旦処理を分けたほうがいい。

Javaのソースファイルがあれば、Eclipseなどでプロファイルを取ったほうが早く問題点が見つかるかもしれません。

jstat参考URL

Java Platform, Standard Editionツール・リファレンス

https://docs.oracle.com/javase/jp/8/docs/technotes/tools/windows/jstat.html

https://docs.oracle.com/javase/jp/13/docs/specs/man/jstat.html

jstatのgcutilオプション使用時の説明
https://qiita.com/sengoku/items/03939ce47363f2b69803

最後に

JDKには、あまり知られていないプログラム解析用の便利なツールが含まれています。

Oracleの公式サイトにJDKツールとユーティリティの説明があります。

https://docs.oracle.com/javase/jp/8/docs/technotes/tools/index.html

Javaプログラムのハングアップ(応答なし)の調査ツール jstack/jpsJavaプログラムのハングアップ(応答なし)などの調査に使えるツールjstackを紹介します。 jstackの使い方 Win...
Windows Java環境構築(JDKインストール)Javaでプログラム開発を行うには、JDKのインストールが必要です。 JDKとはJava Development Kitの略称です...
CentOS_java-yumインストール
CentOSにJava(openJDK)をyumでインストールする手順と複数バージョンの切り替え方法CentOS に yumで Java 8(openJDK) をインストールする手順と複数バージョンの切り替え方法について説明します。 ...