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
JVMの使用メモリサイズの解析
jstatコマンドの出力から、実際に使用しているメモリを調査します。
jstatで使用しているメモリを調査
使用メモリの大まかな推移を見るのは、jstatの出力の”O”(OLD領域の使用率)の項目に着目すれば傾向が分かります。
Timestampの数値を横軸、「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