Java アプリケーション用のデバッグ ツールを作成することを考えています。
Exception.printStackTrace()
実際に例外をスローすることなく、スタック トレースを取得できるかどうか疑問に思っています。
私の目標は、特定のメソッドでスタックをダンプして、メソッドの呼び出し元が誰であるかを確認することです。
Java アプリケーション用のデバッグ ツールを作成することを考えています。
Exception.printStackTrace()
実際に例外をスローすることなく、スタック トレースを取得できるかどうか疑問に思っています。
私の目標は、特定のメソッドでスタックをダンプして、メソッドの呼び出し元が誰であるかを確認することです。
はい、単に使用します
Thread.dumpStack()
Thread.getAllStackTraces()
生きているすべてのスレッドのスタック トレースのマップを取得する
こともできます。 </p>
(Ram の提案のように、システム内のすべてのスレッドではなく) 現在のスレッドのみのトレースが必要な場合は、次のようにします。
Thread.currentThread()。getStackTrace()
発信者を見つけるには、次のようにします。
private String getCallingMethodName() {
StackTraceElement callingFrame = Thread.currentThread().getStackTrace()[4];
return callingFrame.getMethodName();
}
そして、呼び出し元を知る必要があるメソッド内からそのメソッドを呼び出します。ただし、注意が必要です。リスト内の呼び出しフレームのインデックスは、JVM によって異なる可能性があります。それはすべて、トレースが生成されるポイントに到達する前に getStackTrace 内に呼び出しのレイヤーがいくつあるかによって異なります。より確実な解決策は、トレースを取得し、それを繰り返し処理して getCallingMethodName のフレームを探し、さらに 2 つの手順を実行して真の呼び出し元を見つけることです。
次のようなスタック トレースを取得できます。
Throwable t = new Throwable();
t.printStackTrace();
フレームにアクセスしたい場合は、t.getStackTrace() を使用してスタック フレームの配列を取得できます。
ホットスポット コンパイラが最適化に忙殺されている場合、このスタック トレース (他のスタック トレースと同様) で一部のフレームが欠落している可能性があることに注意してください。
Java 9 ではStackWalker
、スタックをウォークするための およびサポート クラスが導入されました。
Javadoc の一部を次に示します。
このメソッドは、現在のスレッドの
walk
シーケンシャル ストリームを開き、指定された関数を適用してストリームをウォークします。ストリームは、スタックが生成された実行ポイントを表す一番上のフレームから一番下のフレームまで、スタック フレーム要素を順番に報告します。walk メソッドが戻ると、ストリームは閉じられます。クローズされたストリームを再利用しようとすると、スローされます。StackFrames
StackFrame
StackFrame
IllegalStateException
...
現在のスレッドの上位 10 個のスタック フレームのスナップショットを作成するには、
List<StackFrame> stack = StackWalker.getInstance().walk(s -> s.limit(10).collect(Collectors.toList()));
また、プロセスに 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
キャプチャ出力が必要な場合
StringWriter sw = new StringWriter();
new Throwable("").printStackTrace(new PrintWriter(sw));
String stackTrace = sw.toString();
コードでこれを行う必要さえありません。Java HPROF をプロセスにアタッチし、いつでも Control-\ を押して、ヒープ ダンプや実行中のスレッドなどを出力できます。. . アプリケーションコードを台無しにする必要はありません。これは少し時代遅れです。Java 6 には GUI jconsole が付属していますが、それでも HPROF は非常に便利だと思います。