Відповіді:
Так, просто використовуйте
Thread.dumpStack()
public static void dumpStack() { new Exception("Stack trace").printStackTrace(); }
stderr
, що, мабуть, є наслідком цього питання.
Якщо ви хочете простежити лише поточний потік (а не всі потоки в системі, як це пропонує пропозиція Рама), зробіть:
Thread.currentThread (). getStackTrace ()
Щоб знайти абонента, виконайте:
private String getCallingMethodName() {
StackTraceElement callingFrame = Thread.currentThread().getStackTrace()[4];
return callingFrame.getMethodName();
}
І називати цей метод ізсередини методу, який повинен знати, хто його викликає. Однак слово попередження: індекс кадру виклику в списку може змінюватися залежно від JVM! Все залежить від того, скільки шарів дзвінків є в getStackTrace, перш ніж потрапити в точку, де генерується слід. Більш надійним рішенням було б отримати слід і перебрати його, шукаючи кадр для getCallingMethodName, а потім зробити два кроки далі, щоб знайти справжнього абонента.
Ви можете отримати такий слід стека:
Throwable t = new Throwable();
t.printStackTrace();
Якщо ви хочете отримати доступ до кадру, ви можете використовувати t.getStackTrace (), щоб отримати масив фреймів стеків.
Майте на увазі, що в цьому стек-трасі (як і в будь-якому іншому) можуть бути відсутні кадри, якщо компілятор точки доступу зайнятий оптимізацією речей.
t.printStackTrace
на t.printStackTrace(System.out)
.
log.log(Level.SEVERE, "Failed to do something", new Throwable());
Зауважте, що Thread.dumpStack () насправді викидає виняток:
new Exception("Stack trace").printStackTrace();
Ви також можете надіслати сигнал до JVM для виконання Thread.getAllStackTraces () у запущеному процесі Java, надіславши сигнал QUIT до цього процесу.
Для використання Unix / Linux:
kill -QUIT process_id
, де process_id - номер процесу вашої програми Java.
У Windows ви можете натиснути Ctrl-Break у програмі, хоча ви зазвичай цього не бачите, якщо не запустите консольний процес.
JDK6 представив інший варіант, команду jstack, яка відображатиме стек з будь-якого запущеного процесу JDK6 на вашому комп'ютері:
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 9 представила StackWalker
та допоміжні класи для ходьби стеком.
Ось кілька фрагментів Javadoc:
walk
Метод відкриває послідовний потікStackFrames
для поточного потоку , а потім застосовує цю функцію , щоб йти поStackFrame
течії. Потік повідомляє про елементи кадру стека в порядку, від самого верхнього кадру, який представляє собою точку виконання, в якій сформований стек, до самого нижнього кадру.StackFrame
Потік закривається , коли метод повертає ходьби. Якщо буде зроблена спроба повторного використання закритого потоку,IllegalStateException
буде кинуто....
Щоб зробити знімок топ-10 кадрів стека поточної нитки,
List<StackFrame> stack = StackWalker.getInstance().walk(s -> s.limit(10).collect(Collectors.toList()));
Вам навіть не потрібно робити це в коді. Ви можете приєднати Java HPROF до свого процесу та в будь-який момент натиснути клавішу Control- \, щоб вивести накопичувач, купуючи нитки тощо. . . не мукуючи код програми. Це трохи застаріло, Java 6 поставляється з jconsole GUI, але я все ще вважаю HPROF дуже корисним.
Відповідь Роб Ді Марко , безумовно, краще за все, якщо ви раді виходу в stderr
.
Якщо ви хочете скористатися String
новим рядком відповідно до звичайного сліду, ви можете зробити це:
Arrays.toString(Thread.currentThread().getStackTrace()).replace( ',', '\n' );