187

Java アプリケーション用のデバッグ ツールを作成することを考えています。

Exception.printStackTrace()実際に例外をスローすることなく、スタック トレースを取得できるかどうか疑問に思っています。

私の目標は、特定のメソッドでスタックをダンプして、メソッドの呼び出し元が誰であるかを確認することです。

4

10 に答える 10

293

はい、単に使用します

Thread.dumpStack()
于 2009-06-03T14:15:43.257 に答える
86

Thread.getAllStackTraces()生きているすべてのスレッドのスタック トレースのマップを取得する こともできます。 </p>

于 2009-06-03T14:19:44.480 に答える
52

(Ram の提案のように、システム内のすべてのスレッドではなく) 現在のスレッドのみのトレースが必要な場合は、次のようにします。

Thread.currentThread()。getStackTrace()

発信者を見つけるには、次のようにします。

private String getCallingMethodName() {
    StackTraceElement callingFrame = Thread.currentThread().getStackTrace()[4];
    return callingFrame.getMethodName();
}

そして、呼び出し元を知る必要があるメソッド内からそのメソッドを呼び出します。ただし、注意が必要です。リスト内の呼び出しフレームのインデックスは、JVM によって異なる可能性があります。それはすべて、トレースが生成されるポイントに到達する前に getStackTrace 内に呼び出しのレイヤーがいくつあるかによって異なります。より確実な解決策は、トレースを取得し、それを繰り返し処理して getCallingMethodName のフレームを探し、さらに 2 つの手順を実行して真の呼び出し元を見つけることです。

于 2009-06-03T15:28:37.600 に答える
41

次のようなスタック トレースを取得できます。

Throwable t = new Throwable();
t.printStackTrace();

フレームにアクセスしたい場合は、t.getStackTrace() を使用してスタック フレームの配列を取得できます。

ホットスポット コンパイラが最適化に忙殺されている場合、このスタック トレース (他のスタック トレースと同様) で一部のフレームが欠落している可能性があることに注意してください。

于 2009-06-03T14:16:12.023 に答える
10

Java 9 ではStackWalker、スタックをウォークするための およびサポート クラスが導入されました。

Javadoc の一部を次に示します。

このメソッドは、現在のスレッドのwalkシーケンシャル ストリームを開き、指定された関数を適用してストリームをウォークします。ストリームは、スタックが生成された実行ポイントを表す一番上のフレームから一番下のフレームまで、スタック フレーム要素を順番に報告します。walk メソッドが戻ると、ストリームは閉じられます。クローズされたストリームを再利用しようとすると、スローされます。StackFramesStackFrameStackFrameIllegalStateException

...

  1. 現在のスレッドの上位 10 個のスタック フレームのスナップショットを作成するには、

    List<StackFrame> stack = StackWalker.getInstance().walk(s ->
     s.limit(10).collect(Collectors.toList()));
    
于 2017-12-07T14:16:03.140 に答える
7

また、プロセスに QUIT シグナルを送信することにより、JVM にシグナルを送信して、実行中の Java プロセスで Thread.getAllStackTraces() を実行することもできます。

Unix/Linux の場合:

kill -QUIT process_idここで、process_id は Java プログラムのプロセス番号です。

Windows では、アプリケーションで Ctrl-Break を押すことができますが、コンソール プロセスを実行していない限り、通常これは表示されません。

JDK6 では、コンピューター上で実行中の JDK6 プロセスのスタックを表示する jstack コマンドという別のオプションが導入されました。

jstack [-l] <pid>

これらのオプションは、実稼働環境で実行され、簡単に変更できないアプリケーションに非常に役立ちます。これらは、実行時のデッドロックやパフォーマンスの問題を診断するのに特に役立ちます。

http://java.sun.com/developer/technicalArticles/Programming/Stacktrace/ http://java.sun.com/javase/6/docs/technotes/tools/share/jstack.html

于 2009-06-03T16:04:38.690 に答える
7

キャプチャ出力が必要な場合

StringWriter sw = new StringWriter();
new Throwable("").printStackTrace(new PrintWriter(sw));
String stackTrace = sw.toString();
于 2017-04-04T10:50:27.040 に答える
0

HPROF Java プロファイラー

コードでこれを行う必要さえありません。Java HPROF をプロセスにアタッチし、いつでも Control-\ を押して、ヒープ ダンプや実行中のスレッドなどを出力できます。. . アプリケーションコードを台無しにする必要はありません。これは少し時代遅れです。Java 6 には GUI jconsole が付属していますが、それでも HPROF は非常に便利だと思います。

于 2009-06-03T15:38:27.420 に答える