システム管理者として、エラーをまったく作成したり、意味のないエラーメッセージを作成したりせずに、プログラムが異常に動作する状況に直面することがあります。
過去(Javaが登場する前)には、2つの対策がありました:
- 他に何も役に立たない場合–RTFM😉
- 1でも役に立たない場合–システムコールを追跡し、何が起こっているかを確認します
私は通常strace -f
を使用します Linuxでのこのタスクの場合(他のOSにも同様のトレースツールがあります)。これは通常、昔ながらのプログラムではうまく機能しますが、 java で同じことを行うと、トレースが非常にあいまいになります。 -処理する。実際のアクションとは無関係に見えるシステムコールが非常に多いため、そのようなダンプを検索するのはひどいです。
それを行うためのより良い方法はありますか(ソースコードが利用できない場合)?
承認された回答:
ckhanが述べたように、jstack
JVM内のすべてのアクティブなスレッドの完全なスタックトレースを提供するため、優れています。同じことが、SIGQUITを使用してJVMのstderrで取得できます。
もう1つの便利なツールはjmap
です プロセスのPIDを使用してJVMプロセスからヒープダンプを取得できます:
jmap -dump:file=/tmp/heap.hprof $PID
このヒープダンプは、visualvm
などのツールにロードできます。 (これは、jvisualvmという名前の標準のOracle java sdkインストールの一部になりました)。さらに、VisualVMは実行中のJVMに接続して、内部CPU使用率、スレッド数、ヒープ使用量のグラフを表示するなど、JVMに関する情報を表示できます。これは、リークの追跡に最適です。
別のツール、jstat
、数値引数を指定して実行すると、vmstatと同様に、一定期間にわたってJVMのガベージコレクション統計を収集できます(例:vmstat 3
。
最後に、Javaエージェントを使用して、ロード時にすべてのオブジェクトのすべてのメソッドにインストルメンテーションをプッシュすることができます。ライブラリjavassist
これを非常に簡単にするのに役立ちます。したがって、独自のトレースを追加することは可能です。それの難しい部分は、常にではなく、必要なときにのみトレース出力を取得する方法を見つけることです。これにより、JVMのクロールが遅くなる可能性があります。 dtrace
というプログラムがあります これはこのように機能します。試しましたが、あまり成功しませんでした。エージェントがインストルメントできるようになる前にJVMのブートストラップに必要なクラスがロードされるため、エージェントがすべてのクラスをインストルメントできるわけではないことに注意してください。これらのクラスにインストルメンテーションを追加するには遅すぎます。
私の提案 – VisualVMから始めて、JVMの現在のスレッドと重要な統計を表示できるため、知っておくべきことを教えてくれるかどうかを確認します。