IBM i - 仮想マシンのダンプ
他にも、ガベージ・コレクターのパフォーマンスを把握する際に使用可能なツールとして仮想マシンのダンプ(DMPJVM)コマンドがあります。このコマンドにより、JVMに関する情報(初期ヒープ・サイズ、最大ヒープ・サイズ、現在のヒープ・サイズ、JVM開始以降の収集の数などの一部主要GCデータ)を含むスプール・ファイルが提供されます。
この中には、ヒープ内の現在のオブジェクトのダンプも含まれます。これは、オブジェクト・リークの問題を解析する場合に役立ちます(オブジェクト・リークは、アプリケーションで新しいオブジェクトを作成したり、不要になったオブジェクトへの参照を保持したりすることで、コレクターによるオブジェクトの収集が妨げられている場合に発生します)。
DMPJVM出力のGCセクションのサンプル:
Garbage collector parameters
Initial size: 262144 K
Max size: 240000000 K
Current values
Heap size: 449952 K
Garbage collections: 278
Additional values
JIT heap size: 85728 K
JVM heap size: 186588 K
Last GC cycle time: 1302 ms
DMPJVMデータはスナップショットのみで詳細GCで入手できる詳細情報は提供されませんが、DMPJVMはJVMを再起動せずに実行できるため、問題の発生後にJVMに関する一定の情報を取得する場合に役立ちます。
DMPJVMの詳細は、以下のIBM i インフォメーション・センターにあります。http://publib.boulder.ibm.com/iseries/v5r2/ic2924/info/cl/dmpjvm.htm
WRKACTJOBコマンドを使用して、JSM JVMジョブを見つけます。
JSM
JSMJOB QOTHPRDOWN BCH .0 PGM-RUNJSM TIMW
QJVACMDSRV QOTHPRDOWN BCI .0 TIMW
Job: QJVACMDSRV User: QOTHPRDOWN Number: 422841
DMPJVMコマンドを使用して、JVMダンプ情報を含むスプール・ファイルを作成します。
DMPJVM JOB (422841/QOTHPRDOWN/QJVACMDSRV)
JSM JVMでのDMPJVMのサンプル:
Java Virtual Machine Information 422841/QOTHPRDOWN/QJVACMDSRV
........................................................................
Classpath
........................................................................
java.version=1.2
/QIBM/ProdData/Java400/jdk12/lib/jdkptf12.zip:/QIBM/ProdData/Java400/jdk12/lib/rt.jar:/QIBM/ProdData/Java400/jdk12/lib/i18n.jar:/QIBM/ProdData/Java400/ext/IBMmisc.jar:/QIBM/ProdData/Java400/ext/jssl.jar:/QIBM/ProdData/Java400/ext/ibmjssl.jar:/QIBM/ProdData/Java400/:./classes:./jar/activation.jar:./jar/jsm.jar:./jar/jsmnative.jar:./jar/mailapi.jar:./jar/pop3.jar:./jar/smtp.jar:./jar/xalan.jar:./jar/xerces.jar:./jar/xlrd.jar:./jar/jsmservice.jar:./jar/jsmutil.jar:./jar/mail.jar:
........................................................................
Garbage Collection
........................................................................
Garbage collector parameters
Initial size: 2048 K
Max size: *NOMAX
Current values
Heap size: 44032 K
Garbage collections: 51
........................................................................
Thread information
........................................................................
Information for 4 thread(s) of 4 thread(s) processed
Thread: 00000001 Thread-0
TDE: B000100007CCA000
Thread priority: 5
Thread status: Running
Thread group: main
Runnable: java/lang/Thread
Stack:
java/net/PlainSocketImpl.accept(Ljava/net/SocketImpl;)V+1 (PlainSocketImpl
java/net/ServerSocket.implAccept(Ljava/net/Socket;)V+36 (ServerSocket.java
java/net/ServerSocket.accept()Ljava/net/Socket;+8 (ServerSocket.java:224)
com/lansa/jsm/d.if()Lcom/lansa/jsm/a;+0 (:0)
com/lansa/jsm/JSMManager.do(Ljava/lang/String;)V+0 (:275)
com/lansa/jsm/JSMManager.main([Ljava/lang/String;)V+0 (:311)
Locks:
None
Thread: 00000002 Reference Handler
TDE: B0001000070D4000
Thread priority: 10
Thread status: Waiting
Wait object: java/lang/ref/Reference$Lock
Thread group: system
Runnable: java/lang/ref/Reference$ReferenceHandler
Stack:
java/lang/ref/Reference$ReferenceHandler.run()V+48 (Reference.java:129)
Locks:
None
Thread: 00000003 Finalizer
TDE: B000100007CCE000
Thread priority: 8
Thread status: Waiting
Wait object: java/lang/ref/ReferenceQueue$Lock
Thread group: system
Runnable: java/lang/ref/Finalizer$FinalizerThread
Stack:
java/lang/ref/ReferenceQueue.remove(J)Ljava/lang/ref/Reference;+48 (Refere
java/lang/ref/Finalizer$FinalizerThread.run()V+3 (Finalizer.java:190)
Locks:
None
適切な開始点を取得したら、アプリケーションを開始し、処理する最大負荷でしばらくの間実行します。定常状態になるまで時間をおきます(通常は数分で十分です)。システムで負荷生成ツールを使用して定常的な負荷を出力するのが最適です。これにより、実稼働環境ではなく開発環境でのアプリケーションのチューニングが可能になります。
定常的な負荷を提供する(変更の影響度をより正確に確認できる)以外に、ユーザーに影響を与えずに必要な変更を加えることができます。
アプリケーションを実行しているときに、前述のツールを使用して変更の影響度を測定してください。負荷生成ツールによって、スループットや応答時間の詳細もわかるため、アプリケーションのパフォーマンスへの影響を確認できます。
GCのしきい値などのパフォーマンス・パラメータを変更する場合は必ず、スループットや応答時間への影響度を測定し、変更によって実際に効果が出ているかどうかを確認してください。ツールによって改善の余地があることがわかった場合、しきい値を変更して新たに実行を試みます。しきい値を増やしすぎた場合は、スループットが再び低下し始めます。このため、しきい値を下げる必要があります。
このような推奨事項では、大量のヒープ・サイズを処理する主要記憶域がシステムに十分にあることが前提です。実際には必ずしもそうではない場合もあります。
システムのメモリーが制限されている場合は、GCしきい値を低く設定する必要があります。これにより、収集頻度が上がり、ヒープ・サイズが小さくなります。これで、ヒープ全体をメモリー内に保持できます。
システム状況処理(WRKSYSSTS)コマンドを使用して、非データベースのページング/障害率を監視します。
ページング/障害率が高すぎる場合、ヒープが大きすぎる可能性があります。「大きすぎる」の定義は、システム・サイズ、ディスクの数、システム負荷などの各種要因によって異なりますが、通常、Javaプログラムで耐えられる非データベースのページング率が10フォルト/秒を超える場合は問題になります。
高ページング率は、「ウォームアップ」期間は許容されます。
高ページング率は、GCしきい値の設定が高すぎるために発生するか、大きな問題の兆候の可能性があります。
この場合、最初に各自のメモリー・プール内のJVMを分離させます。
これにより、他のアプリケーションがJVMに与える影響が軽減されます。また、問題の原因がGC設定なのか、システム構成なのか、あるいは単に負荷を処理するハードウェアが十分ではないのかを判断することが容易になります。
メモリーが特に制限されている場合、最大ヒープ・サイズを設定すると効果的です。
通常は、省略値*NOMAXのままになっています。これは、GCしきい値に達したときにのみGCが実行されるということです。
最大ヒープ・サイズを設定した場合、コレクターはヒープが最大サイズに達すると必ず実行されます。
ただし、通常のGCとは異なり、最大サイズに達すると、すべてのアプリケーション・スレッドはコレクターの終了を待ってから引き続き実行されます。このため、意図しない中断時間が発生します。
したがって、予想外のヒープの増加を処理し、ヒープが利用可能なメモリーよりも大きくならないようにするセーフティ・ネットとして最大ヒープ・サイズを使用するのが望ましい方法です。
実際に通常の状況下でこの最大サイズに達しないようにGCしきい値を設定する必要があります。
コレクターのチューニングは、GCでの消費時間を短縮する1つの方法です。また、作成されるオブジェクトの数を減らす方法もあります(注:オブジェクトの作成を減らす場合のヒントは、全プラットフォームに共通であり、ドキュメント内のいくつかの箇所で説明されています)。