17

私は非常に巨大なJavaWebベースのアプリケーションに取り組んでいます。開発中に適切なロギングが行われないため、実行順序がわからないため、ブレークポイントを設定してアプリをデバッグするのは非常に困難です。いくつかのアクションを実行した後、実行中のJavaアプリケーションの完全なコールスタックを取得するメカニズムはありますか?

ネットで長い間検索しましたが、具体的な解決策が見つかりませんでした。何かあるかどうか教えてください。ありがとう

4

7 に答える 7

23

方法1:コマンドライン(JDKディストリビューションの一部)からjstackユーティリティを使用します。

方法2:シグナル3をJavaプロセスに送信します。これにより、スタックトレースがstdoutにダンプされます。

方法3:アプリケーション内からThread.getAllStackTraces()を呼び出します。

public class StackTraceDumper
{
    public static dumpAllStackTraces ()
    {
        for (Map.Entry <Thread, StackTraceElement []> entry: 
            Thread.getAllStackTraces().entrySet ())
        {
            System.out.println (entry.getKey ().getName () + ":");
            for (StackTraceElement element: entry.getValue ())
                System.out.println ("\t" + element);
        }
    }
}

次にStackTraceDumper.dumpAllStackTraces()、スタックトレースをダンプする必要がある場所を使用します。

于 2013-02-05T10:44:44.843 に答える
6

Thread.dumpStack() 現在のスレッドのスタックトレースを標準エラーストリームに出力します。 Thread.getAllStackTraces() すべてのライブスレッドのスタックトレースのマップを返します。 Thread.getStackTrace() このスレッドのスタックダンプを表すスタックトレース要素の配列を返します。

于 2013-02-05T10:38:44.500 に答える
5

をご覧くださいThrowable.getStackTrace()。新しいものを作成するだけThrowableです。実際にそうする必要はありませんthrow

于 2013-02-05T10:37:09.787 に答える
3

Ctrl + Breakを押すか、シグナル3を送信する(Unixベースのシステムの場合)ことで、スタックダンプをトリガーできます。スレッドごとにスタックトレースを取得することに注意してください。これは標準エラーになりますので、ロギングがこれをキャプチャしていることを確認してください。

これは、プログラムを介して行うことができます

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

スタックトレースの取得と分析の詳細については、こちらをご覧ください。

お気づきのように、BTraceは別の可能性です。これがそれを使うことについてのSOの答えです。

于 2013-02-05T10:36:27.423 に答える
0

いくつかのオプションがあります:

  • デバッガーで実行し、すべてのスレッドを一時停止すると、それらを検査できます
  • VisualVMを使用して、実行中のプロセスに接続し、スレッドダンプをトリガーします。JDKが付属しています。
  • コマンドラインでjstackを使用して、スレッドをダンプします。

コードにいくつかの基本的なロギングを追加します。

new RuntimeException().printStackTrace();

これにより、静的トレースがstderrに送信されます

于 2013-02-05T10:41:58.807 に答える
0

これらの値をキャプチャしてログに記録するために、AspectJなどのAOPツールを使用してみませんか?after()アドバイスと一緒にexecution()ポイントカットを使用できます。非実稼働デプロイメントの場合、渡された値と戻り値とともにすべてのメソッド呼び出しをログに記録できます。これは、本番環境ではオーバーヘッドが大きすぎます。そのためには、渡された値(AspectJアドバイスで取得したObject args [])をローカル変数に格納し、例外が発生した場合にのみログに記録することができます。ただし、その場合でも、プリミティブ値がBox化されてObject []としてアドバイスに渡されるため、パフォーマンスが低下します。

于 2013-08-16T14:35:28.550 に答える
0

人々がこの投稿を読んで、現在のスレッドのスタックの1つまたは複数のクラスを取得する方法を見つけている場合に備えて:

StackTraceElement[] stack = Thread.currentThread().getStackTrace();
String smallStack = "Calling classes: " + System.lineSeparator() + stack[2] + System.lineSeparator() + stack[3];

これにより、現在のスレッドのスタックが取得されます。

  • stack[0]getStackTrace呼び出し自体になります。
  • stack[1]作業しているコード行になります。
  • つまりstack[2]、これstack[3]が最初の「興味深い」スタック要素です。
于 2021-09-10T07:13:56.810 に答える