Profilowanie Javy jest procesem monitorowania różnych parametrów poziomu JVM, takich jak wykonywanie metod, wykonywanie wątków, tworzenie obiektów i zbieranie śmieci.Możesz uzyskać zrzuty wątków jako plik dziennika wszystkich procesów, które są uruchomione w JVM.Zrzut wątku jest migawką stanu wszystkich wątków, które są częścią określonego procesu.
W linuxie wydając polecenie 'jps’ (narzędzie statusu procesu JVM) można uzyskać oprzyrządowane HotSpot Java Virtual Machines (JVMs) w systemie docelowym z ich odpowiednim ID procesu.
Figura 1- JVMs i ich pids.
Komenda 'jps -l ’ wypisuje pełną nazwę pakietu dla głównej klasy aplikacji lub pełną nazwę ścieżki do pliku JAR aplikacji.Odnieś się do dokumentacji jps po więcej informacji.
Po tym możemy użyć komendy 'jstack’ aby przechwycić zrzuty wątków. narzędzie jstack jest dostarczane w folderze JDK_HOME/bin. Oto polecenie, które musisz wydać aby przechwycić zrzut wątku:jstack <pid>. Tutaj pid jest identyfikatorem procesu aplikacji, której zrzut wątku powinien zostać przechwycony. Tak więc 'jstack 13626′ w mojej konsoli wyświetli następujący log zrzutów wątków, jak pokazano na rysunku.
Wbudowane narzędzia do profilowania i ich implementacja
W dodatku do tych istnieje wiele wbudowanych narzędzi do profilowania JVM takich jak Java VisualVM,Honest Profiler, Async Profiler i Java Mission Controller
Przed zagłębieniem się w te profilery powinniśmy poznać koncepcję 'bezpiecznego punktu’. JVM wewnętrznie zajmuje się wieloma rzeczami za nas, takimi jak Garbage Collection i kompilacja JIT. Tak więc JVM potrzebuje również własnego czasu, aby uporządkować pewne rzeczy dla siebie, poza aplikacją. Niektóre z rzeczy, które JVM może zrobić, mogą obejmować safepoint (w tym GC). Podczas safepoint, wszystkie wątki wykonujące kod Java są zawieszone, aby JVM mogła wykonać swoją pracę. Tak więc niektóre profilery cierpią z powodu tych problemów safepoint, gdzie dają wywołanie zwrotne do określonych wątków, te wątki powinny być w safepoint, aby odpowiedzieć na to wywołanie zwrotne.Tak więc wpływa to na wydajność.
Z drugiej strony niektóre profilery używają openJDK wewnętrznego API wywołania AsyncGetCallTrace (ASGT), aby ułatwić nie-safepoint zbieranie śladów stosu. AsyncGetCallTrace NIE jest oficjalnym API JVM.Aby użyć ASGT najpierw stwórz agenta JVMTI .Java Virtual Machine Tool Interface (JVMTI) zapewnia interfejs programistyczny, który pozwala Tobie, programiście, na tworzenie agentów programistycznych, które mogą monitorować i kontrolować Twoje aplikacje w języku programowania Java.Następnie skonfiguruj signal handler, który wyzwala sygnał z żądaną częstotliwością próbkowania.Sygnał ten zostanie skierowany do uruchomionej maszyny JVM, a jeden z jej uruchomionych wątków zostanie przerwany i oddzwoni do naszego handler’a sygnału.Upewnij się, że przerwany wątek jest uruchomiony w twoim handlerze sygnału i wywołaj AGCT .Honest profiler użyj tego ASGT do wykonania profilowania .
The Honest profiler ma dwie części do niego. Agent C++ JVMTI, który wypisuje plik zawierający wszystkie informacje o profilowaniu aplikacji, do której agent jvmti został dołączony.Druga część, to aplikacja Java, która renderuje profil na podstawie tego dziennika, który został wcześniej wygenerowany.
Metoda ASGT będzie wyglądać tak. AsyncGetCallTrace(ASGCT_CallTrace *trace,jint depth,void* ucontext) .Powinniśmy przekazać wskaźnik do śladu wywołania ASGT do tej metody.
Problem z tym podejściem polega na tym, że otrzymujemy nieco inne dane niż typowy ślad stosu Javy. Profiler musi go przetworzyć i zmapować do linii w kodzie źródłowym, aby był użyteczny.
Async profiler to profiler o niskim narzucie próbkowania, który działa poprzez dołączenie natywnego agenta Java do uruchomionego procesu JVM i zbieranie próbek śladów stosu za pomocą interfejsów API specyficznych dla HotSpot. Async-profiler działa tylko na GNU/Linux i MacOS, a na tym pierwszym, dodatkowo wykorzystuje perf_events do grzebania w natywnym kodzie. Ogólnym podejściem jest otrzymywanie stosów wywołań generowanych przez perf_events i dopasowywanie ich do stosów wywołań generowanych przez AsyncGetCallTrace, w celu wytworzenia dokładnego profilu zarówno Java jak i natywnego kodu. Używa API perf_events do skonfigurowania próbkowania CPU do bufora pamięci i prosi o sygnał, który ma być dostarczony, gdy pojawi się próbka. Następnie handler sygnału wywołuje AGCT i łączy dwa stosy razem: stos Javy, przechwycony przez AGCT, oraz stos natywny + stos jądra, przechwycony przez perf_events. Dla wątków nie-Javy, tylko stos perf_events jest zachowany.
Java Mission Controller(JMC) daje szczegółowy raport każdego z konkretnych wątków w każdej JVM i ich procentowe zużycie CPU w efektywny sposób.Java Mission Control działa poprzez interakcję z agentem JMX w JVM, który ma serwer MBean, który integruje się z wbudowaną maszyną wirtualną i instrumentacją aplikacji działającą w JVM. Jest to kluczowa zaleta, ponieważ naprawdę obniża koszty ogólne narzędzia, ponieważ używa wcześniej istniejących haków. Oracle twierdzi, że jest to zwykle znacznie poniżej 1% overhead.Here nie ma nic, że trzeba zainstalować lub dołączyć do istniejącej maszyny wirtualnej, aby uzyskać to działa. W przypadku Flight recorder jest kilka flag, które trzeba włączyć, ale nie trzeba nic instalować. Uruchom terminal i przejdź do katalogu JDK bin i wpisz jmc.JMC wyświetli GUI zawierające działające maszyny JVM.Wybierz proces JVM, który chcesz profilować i rozpocznij nagrywanie, określając limit czasu.
Inną popularną alternatywą jest użycie Linux perf, który nie wspiera bezpośrednio Javy, ale ma świetne wsparcie dla profilowania natywnego kodu, i nie ma problemów z patrzeniem na stosy jądra. Do obsługi JVM potrzebujemy mapy perf, która mapuje skompilowane przez JIT adresy na nazwy funkcji (jako następstwo, tylko skompilowane ramki są obsługiwane; ramki interpretera są niewidoczne)
Oraz przełącznika JIT -XX:+PreserveFramePointer, który upewnia się, że perf może chodzić po stosie Javy. Kiedy używasz tego rodzaju podejścia, kończysz tracąc ramki interpretera.Nie możesz profilować starszej JVM, która nie ma flagi PreserveFramePointer.W twojej perfmapie może być kilka nieaktualnych wpisów, ponieważ JIT może przekompilować kod.Ponieważ JIT wyrzuca część kodu, niektóre funkcjonalności mogą skończyć się z niewłaściwą implementacją.
W dodatku do tych Java 2 Platform Standard Edition (J2SE) zawsze dostarczała proste narzędzie do profilowania z linii poleceń o nazwie HPROF do profilowania sterty i cpu. HPROF jest narzędziem wbudowanym w JDK do profilowania użycia CPU i sterty w JVM.HPROF jest właściwie natywną biblioteką agenta JVM, która jest dynamicznie ładowana przez opcję wiersza poleceń, przy starcie JVM, i staje się częścią procesu JVM. Poprzez dostarczenie opcji HPROF przy starcie, użytkownik może zażądać od HPROF różnego rodzaju funkcji profilowania sterty i/lub procesora. Wygenerowane dane mogą być w formacie tekstowym lub binarnym i mogą być użyte do śledzenia i izolowania problemów z wydajnością związanych z wykorzystaniem pamięci i nieefektywnym kodem. Plik w formacie binarnym z HPROF może być używany z narzędziami takimi jak HAT do przeglądania zaalokowanych obiektów w stercie.
Wnioski
Zauważamy, że uczciwe profilowanie i profilowanie Async przezwyciężyły anomalię 'Cierpienia z powodu safepointów’ przez wewnętrzne wywołanie API OpenJDK AsyncGetCallTrace.Mogą one wykonywać profilowanie z dużo mniejszymi narzutami niż standardowe narzędzia profilowania.Ale nie mogą zapewnić szczegółowego profilowania wątków, które są specyficzne dla procesów JVM oddzielnie.Mogą one tylko wyprowadzić plik dziennika / interfejs GUI całego zrzutu wątków jako grupy.Z drugiej strony Java Mission Control może profilować wątki, które są specyficzne dla każdego procesu oddzielnie, gdzie można monitorować gorące wątki z ich wykorzystania CPU.Tak więc JMC jest najlepszą opcją do monitorowania parametrów JVM z dużą granularity.
References.
Java Virtual Machine Process Status Tool Oracle Documentation.
https://docs.oracle.com/javase/7/docs/technotes/tools/share/jps.html
Creating a Debugging and Profiling Agent with JVMTI
http://www.oracle.com/technetwork/articles/java/jvmti-136367.html
The Pros and Cons of AsyncGetCallTrace Profilers
http://psy-lob-saw.blogspot.com/2016/06/the-pros-and-cons-of-agct.html
A sampling JVM profiler without the safepoint sample bias-.Honest Profiler
https://github.com/jvm-profiling-tools/honest-profiler
Próbkujący profiler CPU i HEAP dla Javy z AsyncGetCallTrace + perf_events
https://github.com/jvm-profiling-tools/async-profiler
.