Jak prześledzić program Java?


25

Jako administrator systemu czasami spotykam się z sytuacjami, w których program zachowuje się nienormalnie, nie generując wcale błędów lub tworząc nonsensowne komunikaty o błędach.

W przeszłości - zanim pojawiła się java - istniały dwa środki zaradcze:

  1. Jeśli nic innego nie pomoże - RTFM ;-)
  2. Jeśli nawet 1. nie pomaga - prześledzić wywołania systemowe i zobaczyć, co się dzieje

Zwykle używam strace -fdo tego zadania w systemie Linux (inne systemy operacyjne mają podobne narzędzia do śledzenia). Teraz, chociaż zwykle działa to dobrze w przypadku każdego staromodnego programu, ślad staje się bardzo niewyraźny, gdy robi się to samo w procesie Java . Jest tak wiele wywołań systemowych pozornie niezwiązanych z żadnym rzeczywistym działaniem, że przeszukiwanie takiego zrzutu jest okropne.

Czy są lepsze sposoby na to (jeśli kod źródłowy nie jest dostępny)?

Odpowiedzi:


16

Jak wspomniano ckhan, jstackjest świetny, ponieważ daje pełny ślad wszystkich aktywnych wątków w JVM. To samo można uzyskać na stderr JVM przy użyciu SIGQUIT.

Innym przydatnym narzędziem jest jmappobieranie zrzutu sterty z procesu JVM za pomocą PID procesu:

jmap -dump:file=/tmp/heap.hprof $PID

Ten zrzut sterty można załadować w narzędziach takich jak visualvm(który jest teraz częścią standardowej instalacji Oracle Java Java SDD, o nazwie jvisualvm). Ponadto VisualVM może łączyć się z działającą maszyną JVM i wyświetlać informacje o JVM, w tym pokazywać wykresy zużycia wewnętrznego procesora, liczby wątków i zużycia sterty - idealne do śledzenia wycieków.

Inne narzędzie, jstatmoże zbierać statystyki zbierania śmieci dla JVM przez okres podobny do vmstat, gdy jest uruchamiany z argumentem numerycznym (np vmstat 3.).

Wreszcie można użyć agenta Java do wypychania instrumentacji na wszystkie metody wszystkich obiektów podczas ładowania. Biblioteka javassistmoże pomóc uczynić to bardzo łatwym do zrobienia. Można więc dodać własne śledzenie. Trudność polega na znalezieniu sposobu na uzyskanie danych wyjściowych śledzenia tylko wtedy, gdy tego chcesz, a nie przez cały czas, co prawdopodobnie spowolniłoby JVM do przeszukiwania. Istnieje program o nazwie, dtracektóry działa w taki sposób. Próbowałem, ale nie odniosłem sukcesu. Zauważ, że agenci nie mogą instrumentować wszystkich klas, ponieważ te potrzebne do załadowania JVM są ładowane, zanim agent może instrumentować, a wtedy jest za późno, aby dodać instrumentację do tych klas.

Moja sugestia - zacznij od VisualVM i sprawdź, czy powie ci to, co musisz wiedzieć, ponieważ może pokazywać bieżące wątki i ważne statystyki dla JVM.


Nawiasem mówiąc, jest to niesamowite pytanie; Mam nadzieję, że więcej osób doda odpowiedzi z innymi pomysłami. Kiedy zapytałem ludzi pracujących z Javą przez wiele lat o śledzenie, dali mi puste spojrzenia. Być może po prostu nie znają niesamowitości strachu.
popiół

10

Z tej samej próżności podczas debugowania programów, które nie działały poprawnie w systemie Linux, można użyć podobnych narzędzi do debugowania uruchomionych maszyn JVM w systemie.

Narzędzie nr 1 - jvmtop

Podobnie top, możesz użyć jvmtop, aby zobaczyć, jakie są klasy w uruchomionych maszynach JVM w twoim systemie. Po zainstalowaniu wywołujesz go w następujący sposób:

$ jvmtop.sh

Jego dane wyjściowe są podobnie zaprojektowane, aby wyglądały jak narzędzie top:

 JvmTop 0.8.0 alpha   amd64  8 cpus, Linux 2.6.32-27, load avg 0.12
 http://code.google.com/p/jvmtop

  PID MAIN-CLASS      HPCUR HPMAX NHCUR NHMAX    CPU     GC    VM USERNAME   #T DL
 3370 rapperSimpleApp  165m  455m  109m  176m  0.12%  0.00% S6U37 web        21
11272 ver.resin.Resin [ERROR: Could not attach to VM]
27338 WatchdogManager   11m   28m   23m  130m  0.00%  0.00% S6U37 web        31
19187 m.jvmtop.JvmTop   20m 3544m   13m  130m  0.93%  0.47% S6U37 web        20
16733 artup.Bootstrap  159m  455m  166m  304m  0.12%  0.00% S6U37 web        46

Narzędzie nr 2 - jvmmonitor

Inną alternatywą jest użycie jvmmonitor . JVM Monitor to profiler Java zintegrowany z Eclipse do monitorowania zużycia procesora, wątków i pamięci przez aplikacje Java. Możesz użyć go do automatycznego znalezienia uruchomionych maszyn JVM na lokalnym hoście lub połączyć się ze zdalnymi maszynami JVM za pomocą portu @ host.

ss jvmmonitor

Narzędzie nr 3 - visualvm

visualvm jest prawdopodobnie „narzędziem”, do którego można sięgać podczas debugowania problemów z JVM. Jego zestaw funkcji jest dość głęboki i można bardzo głęboko przyjrzeć się wnętrznościom.

Profiluj działanie aplikacji lub analizuj przydział pamięci:

ss visualvm # 2

Pobieraj i wyświetlaj zrzuty wątków:

ss visualvm # 3

Referencje



2

Jeśli używasz RHEL OpenJDK (lub podobnie, chodzi o to, że nie jest to JDK Oracle), możesz do tego użyć SystemTap .

Niektóre sondy są włączane za pomocą opcji wiersza poleceń java -XX:+DTraceMethodProbes, -XX:+DTraceAllocProbes, -XX:+DTraceMonitorProbes. Pamiętaj, że włączenie tych sond znacząco wpłynie na wydajność programu.

Oto przykładowy skrypt SystemTap:

#!/usr/bin/stap

probe hotspot.class_loaded {
    printf("%12s [???] %s\n", name, class);
}

probe hotspot.method_entry, 
      hotspot.method_return {
    printf("%12s [%3d] %s.%s\n", name, thread_id, class, method);
}

probe hotspot.thread_start, 
      hotspot.thread_stop {
    printf("%12s [%3d] %s\n", name, id, thread_name);
}

probe hotspot.monitor_contended_enter, 
      hotspot.monitor_contended_exit {
    printf("%12s [%3d] %s\n", name, thread_id, class);
}

Możesz także użyć, jstack()aby uzyskać stos Java procesu, ale zadziała to tylko wtedy, gdy uruchomisz SystemTap przed JVM.


Zauważ, że SystemTap będzie śledził każdą metodę. Nie jest również w stanie uzyskać argumentów metody. Inną opcją jest użycie własnych możliwości śledzenia JVM, które nazywa się JVMTI. Jedną z najbardziej znanych implementacji JVMTI jest BTrace .


0

Zaleca się wypróbowanie Jackplay , który jest narzędziem śledzenia JVM, umożliwiającym śledzenie wejścia i wyjścia metody bez zmiany kodu lub ponownego wdrożenia.


Nie można dołączyć go do działającej maszyny JVM. Poza tym - ciekawe narzędzie
Nils
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.