メモリ・リークの発見方法
こうしたJavaプログラムのメモリ・リークを発見するには、例えば米Sitrakaの「JProbe」( http://www.sitraka.com/)など市販のプロファイラ・ツールがよく利用されます。またHP-UXであれば、OS付属のモニタリング・ツール「Glance/gpm」の「Memory Regions」画面がメモリ・リークの発見に大変役に立ちます。具体的には、監視対象とするJVMプロセス(javaという名前のプロセス)を選択し、同プロセスが使用するすべてのメモリ領域のレポートを生成します。これにより、以下のような画面が表示されます。
図3において、Data RSS(resident set size)およびData VSS(virtual set size)のそれぞれの値が、JVMを実装するCプログラムが使用するメモリ・サイズを示します。一方、Other RSSとOther VSS、そしてPrivate RSSは、JVM内部のヒープ・メモリを含んでいます。これらの領域のうちいずれかに継続的な増加が見られる場合、そのJavaプログラムはメモリ・リテンションの問題を抱えているとみて間違いないでしょう。
また、JVMのメモリ・リークの原因は、メモリ・リテンション以外にも考えられます。例えば、Javaアプリケーションの中には、CもしくはC++プログラムを内部で呼び出しているものも少なくありません。それらのCもしくはC++プログラムにおいてメモリ・リークが発生しているケースもよくあります。
いずれにせよ、Glance/gpmを利用し、Data RSSやData VSSなどの値の振る舞いを分析することが、メモリ・リークの発見において重要なポイントとなります。
adviser modeの活用
小規模なメモリ・リークについては、Javaプログラムを非常に長い期間に継続して運用して初めて明らかになることがあります。そうした場合は、上記のように画面上で監視し続けるのは現実的ではありません。そこで、メモリ・リークの有無を厳密にテストするときは、Glance/gpmの「adviser mode」を活用します。
adviser modeとは、Glance/gpmのGUIを起動せず、バッチ形式で動作させるモードのことです。これにより、長期間にわたって収集した大量のデータをファイルに出力し、後ほどゆっくり分析することができます。以下は、Glance/gpmのadviser modeを利用して5秒ごとにサンプルを採取するコマンドの例です。
$ /opt/perf/bin/glance -adviser_only -syntax adviser_commands -j 1
ここでは指定されている「adviser_commandsファイル」には、計測に使用するコマンドを以下のような書式で記述しておきます。
PRINT "----- ", gbl_stattime, " (proc name, pid, cpu, negnice cpu, VSS, RSS, thread #, I/O)" PROCESS LOOP { if proc_proc_name == "java" then { PRINT proc_proc_name|8|0, proc_proc_id|8|0, proc_cpu_total_util|8|2, proc_cpu_nnice_time|8|2, proc_mem_virt, proc_mem_res, proc_thread_count, proc_io_byte_rate } }
上述のコマンドを実行すると、メモリ計測の結果が以下のようにファイルに出力されます。
----- 20:15:37 (proc name, pid, cpu, negnice cpu, VSS, RSS, thread #, I/O) java 6390 93.33 0.00 787.9mb 389.7mb 2438 0.0 java 6370 88.66 0.00 788.9mb 308.3mb 2444 0.0 ----- 20:15:38 (proc name, pid, cpu, negnice cpu, VSS, RSS, thread #, I/O) java 6390 80.00 0.00 793.8mb 389.7mb 2482 0.0 java 6370 74.66 0.00 794.7mb 308.3mb 2488 0.0 <以下略>
ここでは、VSSのサイズが継続的に増加していることが分かります。メモリ・リークを検出する手段としては、Glance/gpm以外にも以下のような方法があります。
- JVMオプション-Xverboseegcから得られるログを解析する
- HPjmeterによるメモリ・リークの解析
- gdb(gnu debugger)を用いる
以上、今回はJavaプログラムによるメソッド・コールの調査、そしてメモリ・リークの発見について説明しました。次回は引き続き、HPjmeterによるメモリ・リークの解析について詳しく説明します。
本記事は、HP-UX Developer Edgeに掲載された「連載 Javaパフォーマンスチューニング」を株式会社アットマーク・アイティおよび本記事の筆者が独自の判断のもとに加筆・修正したものです。
Copyright © ITmedia, Inc. All Rights Reserved.