Java仮想マシンの監視および診断ツールについて話す

1.基本的なコマンドの適用

1.1 jps(ソース操作ドキュメント

デフォルトでは、jpsの出力情報には、JavaプロセスのプロセスIDとメインクラスの名前が含まれます。パラメータを追加して、追加情報を印刷することもできます。Javaプロセスがデフォルトで有効になっているUsePerfDataパラメーターをオフにした場合(つまり、パラメーター-XX:-UsePerfDataを使用)、jpsコマンド(および以下で説明するjstat)はJavaプロセスを検出できません。

一般的に使用されるパラメーター:

-l:モジュール名とパッケージ名が出力されます。

-v:Java仮想マシンに渡されたパラメーターを出力します(-XX:+ UnlockExperimentalVMOptions -XX:+ UseZGCなど)。

-m:メインクラスに渡されたパラメーターを出力します。

1.2 jstat(ソース操作ドキュメント

jstatコマンドを使用して、ターゲットJavaプロセスのパフォーマンスデータを出力できます。

-class:印刷クラスの関連データをロードします。

-compilerおよび-printcompilation:インスタントコンパイルに関連するデータを出力します。

-gc:プレフィックスサブコマンド。ガベージコレクション関連のデータを出力します。

たとえば、コマンド:jstat -gc 22126 1s 4は、毎秒1回印刷し、4回印刷することを意味します。

1.3 jmap(ソース操作ドキュメント

jmapコマンドは、Java仮想マシンヒープ内のオブジェクトを分析します。jmapには、複数のサブコマンドも含まれています。

-clstats、このサブコマンドは、ロードされたクラスの情報を出力します。

-finalizerinfo、このサブコマンドは、ファイナライズするすべてのオブジェクトを出力します。

-histo、このサブコマンドは、各クラスのインスタンスの数と占有されているメモリをカウントし、メモリ使用量が少ない順に並べます。加えて、

-histo:liveは、ヒープ内のライブオブジェクトのみをカウントします。

-dump、このサブコマンドは、Java仮想マシンヒープのスナップショットをエクスポートします。liveは、ライブオブジェクトをヒープに保存するだけです。私たちは通常jmaを使用します

1.4 jinfo(ソース操作ドキュメント

jinfoコマンド(ヘルプドキュメント)を使用して、ターゲットJavaプロセスのパラメーターを表示できます。

-X:Java仮想マシンでjvm_argsを出力します

-XX:JavaレベルのSystem.getPropertyを介して取得できるパラメーター(つまり、出力のVMフラグ)および-Dパラメーター(つまり、出力のシステムプロパティ)。

1.5 jstack(ソース操作ドキュメント

jstackコマンド(ヘルプドキュメント)を使用して、ターゲットJavaプロセスの各スレッドのスタックトレースと、これらのスレッドによって保持されているロックを出力できます。jstackのアプリケーションシナリオの1つは、デッドロックの検出です。ここでは、jstackを使用して、デッドロックされたJavaプログラムのスタック情報を取得します。jstackは、スレッドスタックトレース、スレッドステータス(BLOCKED)、保留中のロック(locked ...)、および要求されているロック(lockingを待機中...)を出力するだけでなく、特定のデッドロックも分析していることがわかります。

1.6 jcmd(ソース操作ドキュメント

jcmdコマンドを直接使用して、jstatを除く以前のすべてのコマンドを置き換えることができます。jstatの機能については、jcmdはjstatのコードの一部をコピーし、PerfCounter.printサブコマンドによるすべてのパフォーマンスカウンターの印刷をサポートしますが、jstatの出力形式を保持せず、印刷を繰り返す機能もありません。

(上記の内容は、侵入や削除など、オタク時代のJVMの学習内容に関する学習ノートです)

2.自分の練習

2.1背景

以下に、無限ループをシミュレートするプログラムを示し、システム内のプログラムを監視して除外します。まず第一に、このプログラムに無限ループがあるかどうかを認識できません。次に、プログラムを監視および調査します。

画像

2.1プログラムを監視する

1.最初にjpsと入力して、実行中のサービスでJavaプログラムを表示します。

画像

2.コマンドjstat-gc 6388 1s 20を使用して、プログラムの仮想マシンの動作を表示します。

まず、-gcパラメーターの出力パラメーターの基本を理解します。

S0C:第一个幸存区的大小
S1C:第二个幸存区的大小
S0U:第一个幸存区的使用大小
S1U:第二个幸存区的使用大小
EC:伊甸园区的大小
EU:伊甸园区的使用大小
OC:老年代大小
OU:老年代使用大小
MC:方法区大小
MU:方法区使用大小
CCSC:压缩类空间大小

画像

上記では、jstat -gc xxxxx 5s100コマンドを使用してjvmのパフォーマンスを表示しました

上の図の緑色は、主にEU、OU、YGCを含むjvmのパフォーマンスデータを監視するためのものであることがわかります。

まず、緑色のデータセットを見てください。

gcの20〜21 gcで、s1uが空になり、s0uが増加しました。gcにより、s1uの存続オブジェクトとedn領域でプロモートされたオブジェクトがs0u領域にコピーされ、s1uのオブジェクトが空になりました。

次に、黄色と赤のデータを見てください。

OU内のデータは基本的に大幅に増加し、su領域内のデータは減少していることがわかります。これは、期間中に、su領域内のオブジェクトを旧世代に昇格させるためにフルgcが実行されたためです。

上記のデータを見ると、jvmの基本的な内部操作しか見えず、異常かどうかはわかりませんが、使い慣れたプログラムの基本的な手がかりはわかります。短期間で再びgcになっているので、観察を続けましょう。

画像

次に、同じコマンドを見てください。

最初にOUとOCの値を観察します。OUは増加し続け、値はOCに非常に近いため、プログラムはすぐにOutOfMemoryErrorをスローします。これは、非常に重大なエラーです。したがって、jvmのこれら2つの値の比率に注意してください。合理的な状況によれば、OUを長時間実行するプログラムは、より安定していて、上下に応じて変動するはずですが、プログラムの値がOUであること。値が再び増加し、成長率が異常な場合は、プログラムにバグがあるはずです。教育内容によると、OUは通常OCの20%未満を占めており、20%を超える場合は、早期警告が必要です。OutOfMemoryErrorの手がかりはすでにあります。

最初に、完全なgcが30秒の短い期間で実行され、プログラムはこの増加率でさらに30秒後にクラッシュしました。実際、それは本当に崩壊しました。

プログラムの操作に問題が発生したので、次のステップはプログラムを分析することです。

Jstack -l PID >>ファイルの場所を使用して、ビジネスプロセスのすべてのスレッドの実行ステータスを出力できます。

出力後、nidスレッドがビジネスコードであり、常に実行可能であることがわかります。これは、CPUを占有していて、解放できないことを示しています。したがって、この位置に問題がある可能性が非常に高いので、コード、デバッグ、およびその他の操作に精通していることを確認する必要があります。

画像

最後に、killコマンドを使用してプロセスを強制終了します。

1.kill -3 pidは現在のプロセスのスレッド情報を出力できますが、Javaアプリケーションを閉じません!

2. kill -15pidであるkillpidは、フック関数ShutdownHook呼び出します。通常、ShutdownHookは、データの保存、接続の終了など、いくつかの操作を実行します。

3. kill -9pid。フック関数ShutdownHookは呼び出されません

3.個人的な考えの要約:

最も一般的なのはプロジェクトで、無限ループがある場合、占有されていた状況は解放されません。それがWebシステムの一般的な要求のスレッドである場合、通常の要求であり、要求は時間のかかるタスクではなく、迅速に実行されると、複数のスレッドが実行可能状態または待機状態を処理しており、同じメソッド、同じコードが実行され、占有されていることがわかります。現時点では、このメソッドには無限ループが存在する可能性が高くなります。あなたはそれを殺すことができます。ただし、この方法でプログラムを強制終了すると、プログラムの損傷の程度に非常に悪影響を及ぼします。個人的には、この状況を早期に解消するために、無限サイクルを事前に予測して対処し、重大事故の発生を減らすことができたとしても、サイクルにログを追加することをお勧めします。

(能力と時間に限りがありますので、とりあえず分析させていただきます。何かおかしいことがあったら、ぜひみんなで出て修正してほしいです)

おすすめ

転載: blog.csdn.net/vipshop_fin_dev/article/details/112462623