web-dev-qa-db-ja.com

本番環境でのスレッドダンプの取得

スレッドダンプを取得するアプローチの違いを分析しています。以下は私が研究しているカップルです

  1. 宣言されたBean操作をクリックすると、Runtime.exec()を介してjstackをトリガーするjmx Beanを定義します。

  2. 事前定義された間隔の後に「ManagementFactory.getThreadMXBean()。dumpAllThreads(true、true)」を繰り返し実行するデーモンスレッド。

2つのスレッドダンプ出力を比較すると、アプローチ2には次のような欠点があります。

  1. アプローチ2で記録されたスレッドダンプは、TDAなどのオープンソーススレッドダンプアナライザーで解析できません。
  2. 出力には、CPUの高い問題の分析に役立つ可能性があるネイティブスレッドIDが含まれていません(右?)
  3. もう?

私は提案/入力をしていただければ幸いです

  1. 実稼働コードでRuntime.exec()を介してjstackを実行することの欠点はありますか?さまざまなオペレーティングシステムでの互換性の問題-Windows、Linux

  2. スレッドダンプを取得する他の方法はありますか?

ありがとうございました。

編集-

1と2を組み合わせたアプローチが道のりのようです。バックグラウンドで実行されている専用スレッドを使用して、スレッドダンプアナライザーが理解できる形式でログファイル内のスレッドダンプを印刷できます。 jstack出力によってのみログに記録される追加情報(おそらくネイティブスレッドIDなど)が必要な場合は、必要に応じて手動で行います。

21
Andy Dufresne

使用できます

jstack {pid} > stack-trace.log

プロセスが実行されているボックスでユーザーとして実行されます。

これを複数回実行する場合は、diffを使用して、アクティブなスレッドをより簡単に確認できます。


スタックトレースを分析するには、専用のスレッドで定期的にサンプリングされた次のものを使用します。

 Map<Thread, StackTraceElement[]> allStackTraces = Thread.getAllStackTraces();

この情報を使用して、スレッドのID、実行状態を取得し、スタックトレースを比較できます。

33
Peter Lawrey

図のJava 8では、jcmdが推奨されるアプローチです。

jcmd <PID> Thread.print

Oracleドキュメント の抜粋を次に示します。

JDK 8のリリースでは、Java Mission Control、Java Flight Recorder、およびJVMの問題を診断するためのjcmdユーティリティとJava = applications。診断を強化し、パフォーマンスのオーバーヘッドを減らすために、以前のjstackユーティリティの代わりに最新のjcmdユーティリティを使用することをお勧めします。

ただし、これをアプリケーションと一緒に出荷することは、ライセンスへの影響となる可能性がありますが、私にはわかりません。

8
Arnab Biswas

その* nixであれば、kill -3 <PID>、しかし、あなたはプロセスIDを知る必要があり、おそらくあなたはコンソールにアクセスできませんか?

5
Peter Svensson

そのようなenvがある場合はステージング環境ですべてのヒープ分析を行い、必要に応じて本番環境で必要なApplication Serverチューニングを反映することをお勧めします。アプリケーションのメモリ使用率の分析にダンプが必要な場合は、より良い分析のためにプロファイルを検討する必要があります。

ヒープダンプは通常、メモリリークと不適切なメモリ管理に起因するOutOfMemoryExceptionsの結果として生成されます。

Application Serverのドキュメントを確認してください。最新のサーバーのほとんどには、前述の通常の原因とは別に、実行時にダンプを生成する手段があります。

1
Waleed Madanat