Javaプログラムを追跡する方法は?

Javaプログラムを追跡する方法は?

システム管理者として、私は時々プログラムが予期せず動作しますが、エラーがまったく発生しないか、意味のないエラーメッセージを生成する状況に直面しています。

過去には(Java以前は)この問題を処理する2つの方法がありました。

  1. 何も役に立たない場合 - RTFM ;-)
  2. 1. 役に立たない場合 - システムコールを追跡し、何が起こっているかを確認します。

私は通常strace -fこの操作にLinuxを使用します(他のオペレーティングシステムにも同様のトレースツールがあります)。さて、これは一般的にすべての古いプログラムに適用されますが、Java-プロセス。実際の作業とは無関係に見えるシステムコールが多すぎるため、このダンプから検索するのは恐ろしいです。

これを行うより良い方法があります(ソースコードが利用できない場合)。

ベストアンサー1

ckhanが述べたように、jstackJVMのすべてのアクティブスレッドの完全なスタックトレースを提供するので、素晴らしいです。 JVMのstderrでSIGQUITを使用して同じ結果を得ることができます。

別の有用なツールは、jmapプロセスのPIDを使用してJVMプロセスからヒープダンプを取得できることです。

jmap -dump:file=/tmp/heap.hprof $PID

visualvmこのヒープダンプは、jvisualvm(現在の標準のOracle Java SDKインストールの一部)などのツールにロードできます。また、VisualVMは、実行中のJVMに接続して内部CPU使用率、スレッド数、およびヒープ使用量を示すグラフなど、JVMに関する情報を表示できるため、リークトレースに最適です。

数値パラメータ(たとえば)で実行するときにvmstatjstatと同様に、一定期間にわたってJVMのガベージコレクション統計を収集できる別のツールです。vmstat 3

最後に、Javaプロキシを使用して、ロード時にすべてのオブジェクトのすべてのメソッドのインスツルメンテーションをプッシュできます。ライブラリを使用すると、javassistこれを簡単に実行できます。したがって、独自のトレースを追加することが可能です。難しい部分は、常にトレース出力を取得するのではなく、必要なときにのみトレース出力を取得する方法を見つけることです。これによりJVMの速度が遅くなる可能性があります。このように動作するプログラムがありますdtrace。私は試しましたが、それほど成功していませんでした。 JVMを起動するために必要なクラスはエージェントが検出する前にロードされ、そのクラスにインスツルメンテーションを追加するには遅すぎるため、エージェントはすべてのクラスを計測できません。

私のアドバイス- VisualVM から始めて、JVM の現在のスレッドと重要な統計を表示できるので、知っておくべきことを教えてください。

おすすめ記事