Myślę o stworzeniu narzędzia do debugowania dla mojej aplikacji Java.
Zastanawiam się, czy można uzyskać ślad stosu, tak jak Exception.printStackTrace()
ale bez rzucania wyjątku?
Moim celem jest zrzucenie stosu w dowolnej metodzie, aby zobaczyć, kto jest obiektem wywołującym metodę.
public static void dumpStack() { new Exception("Stack trace").printStackTrace(); }
stderr
, co wydaje się być implikacją pytania.Jeśli chcesz śledzić tylko bieżący wątek (a nie wszystkie wątki w systemie, jak sugeruje to Ram), wykonaj:
Thread.currentThread (). getStackTrace ()
Aby znaleźć dzwoniącego, wykonaj:
I wywołaj tę metodę z poziomu metody, która musi wiedzieć, kto jest jej wywołującym. Jednak słowo ostrzeżenia: indeks ramki wywołującej na liście może się różnić w zależności od maszyny JVM! Wszystko zależy od tego, ile warstw wywołań znajduje się w getStackTrace, zanim dotrzesz do punktu, w którym generowany jest ślad. Bardziej niezawodnym rozwiązaniem byłoby pobranie śladu i iteracja po nim w poszukiwaniu ramki dla getCallingMethodName, a następnie wykonanie dwóch kroków dalej, aby znaleźć prawdziwego wywołującego.
źródło
Możesz uzyskać ślad stosu w następujący sposób:
Jeśli chcesz uzyskać dostęp do ramki, możesz użyć t.getStackTrace (), aby uzyskać tablicę ramek stosu.
Należy pamiętać, że w tej ścieżce stosu (podobnie jak w każdym innym) może brakować niektórych ramek, jeśli kompilator punktu aktywnego był zajęty optymalizacją.
źródło
t.printStackTrace
zt.printStackTrace(System.out)
.new Throwable().printStackTrace(System.out);
log.log(Level.SEVERE, "Failed to do something", new Throwable());
Zauważ, że Thread.dumpStack () faktycznie zgłasza wyjątek:
źródło
Możesz również wysłać sygnał do maszyny JVM, aby wykonać Thread.getAllStackTraces () w działającym procesie Java, wysyłając do procesu sygnał QUIT.
W systemie Unix / Linux użyj:
kill -QUIT process_id
, gdzie id_procesu to numer procesu programu Java.W systemie Windows możesz nacisnąć Ctrl-Break w aplikacji, chociaż zwykle tego nie zobaczysz, chyba że uruchomisz proces konsoli.
JDK6 wprowadził kolejną opcję, komendę jstack, która wyświetli stos z dowolnego uruchomionego procesu JDK6 na twoim komputerze:
jstack [-l] <pid>
Te opcje są bardzo przydatne w przypadku aplikacji działających w środowisku produkcyjnym i nie można ich łatwo modyfikować. Są szczególnie przydatne do diagnozowania zakleszczeń w czasie wykonywania lub problemów z wydajnością.
http://java.sun.com/developer/technicalArticles/Programming/Stacktrace/ http://java.sun.com/javase/6/docs/technotes/tools/share/jstack.html
źródło
Jeśli potrzebujesz wyjścia przechwytywania
źródło
Java 9 wprowadziła
StackWalker
i obsługujące klasy do chodzenia po stosie.Oto kilka fragmentów z Javadoc:
źródło
HPROF Java Profiler
Nie musisz nawet tego robić w kodzie. Możesz dołączyć Java HPROF do swojego procesu i w dowolnym momencie nacisnąć Control- \, aby wydrukować zrzut sterty, uruchomić wątki itp. . . bez zepsucia kodu aplikacji. Jest to trochę przestarzałe, Java 6 jest dostarczana z konsolą Jconsole GUI, ale nadal uważam, że HPROF jest bardzo przydatny.
źródło
Odpowiedź Rob Di Marco jest zdecydowanie najlepiej, jeśli są zadowoleni z wyjściem do
stderr
.Jeśli chcesz przechwycić do a
String
, z nowymi wierszami zgodnie ze zwykłym śladem, możesz to zrobić:źródło