Narzędzie do analizy dużych zrzutów sterty Java

80

Mam zrzut sterty JVM HotSpot, który chciałbym przeanalizować. Maszyna wirtualna działała z -Xmx31g, a plik zrzutu sterty ma rozmiar 48 GB.

  • Nawet nie będę próbował jhat, ponieważ wymaga około pięciu razy większej pamięci (w moim przypadku byłoby to 240 GB) i jest strasznie wolny.
  • Eclipse MAT ulega awarii i ArrayIndexOutOfBoundsExceptionpo kilku godzinach analizowania zrzutu sterty.

Jakie inne narzędzia są dostępne do tego zadania? Najlepszym rozwiązaniem byłby zestaw narzędzi wiersza poleceń, składający się z jednego programu, który przekształca zrzut sterty w wydajne struktury danych do analizy, w połączeniu z kilkoma innymi narzędziami, które działają na wstępnie ustrukturyzowanych danych.

Roland Illig
źródło
Czy na pewno zrzut nie jest uszkodzony i że używasz nowszej wersji plików JAR DTFJ? ArrayIndexOutOfBoundsExceptionWyposażony w conajmniej dwóch błędów . Mówię to, ponieważ nie zgłosiłeś OOME podczas uruchamiania MAT, który ma inną poprawkę .
Vineet Reynolds
jhat używa heapMap do przechowywania odczytywanych obiektów, która rośnie wykładniczo wraz z liczbą obiektów przechowywanych w stercie. Jedną z opcji jest zmiana pliku decl z heapMap na TreeMap i uruchomienie rozmiaru sterty jhat co najmniej tak dużego jak twój proces.
codeDr

Odpowiedzi:

80

Zwykle to, czego używam, jest ParseHeapDump.shzawarte w Eclipse Memory Analyzer i opisane tutaj , i robię to na jednym z naszych bardziej rozbudowanych serwerów (pobierz i skopiuj przez dystrybucję linux .zip, rozpakuj tam). Skrypt powłoki potrzebuje mniej zasobów niż parsowanie sterty z GUI, a ponadto można go uruchomić na mocnym serwerze z większą ilością zasobów (można przydzielić więcej zasobów, dodając coś podobnego -vmargs -Xmx40g -XX:-UseGCOverheadLimitna końcu ostatniej linii skryptu. Na przykład: ostatnia linia tego pliku może wyglądać tak po modyfikacji

./MemoryAnalyzer -consolelog -application org.eclipse.mat.api.parse "$@" -vmargs -Xmx40g -XX:-UseGCOverheadLimit

Uruchom to jak ./path/to/ParseHeapDump.sh ../today_heap_dump/jvm.hprof

Po pomyślnym zakończeniu tworzy kilka plików „indeksowych” obok pliku .hprof.

Po utworzeniu indeksów próbuję generować raporty z tego i przesyłać je do moich lokalnych maszyn i próbuję sprawdzić, czy mogę znaleźć winowajcę tylko przez to (nie tylko raporty, nie indeksy). Oto samouczek dotyczący tworzenia raportów .

Przykładowy raport:

./ParseHeapDump.sh ../today_heap_dump/jvm.hprof org.eclipse.mat.api:suspects

Inne opcje raportów:

org.eclipse.mat.api:overview i org.eclipse.mat.api:top_components

Jeśli te raporty nie wystarczą i potrzebuję więcej kopania (np. Przez oql), przeskakuję indeksy, a także plik hprof na moją maszynę lokalną, a następnie otwieram zrzut sterty (z indeksami w tym samym katalogu co zrzut sterty) z moim GUI Eclipse MAT. Stamtąd nie potrzebuje zbyt dużej ilości pamięci do uruchomienia.

EDYCJA: po prostu lubiłem dodać dwie notatki:

  • O ile wiem, tylko generowanie indeksów jest częścią intensywnie korzystającą z pamięci Eclipse MAT. Po uzyskaniu indeksów większość przetwarzania z Eclipse MAT nie wymagałoby tak dużej ilości pamięci.
  • Zrobienie tego na skrypcie powłoki oznacza, że ​​mogę to zrobić na serwerze bezgłowym (i zwykle robię to również na serwerze bezgłowym, ponieważ zwykle są one najpotężniejsze). A jeśli masz serwer, który może wygenerować zrzut sterty o takim rozmiarze, prawdopodobnie masz inny serwer, który może również przetworzyć tak dużą część zrzutu sterty.
Franz See
źródło
4
Ważna uwaga: ParseHeapDump.shjest dostarczana tylko z wersją dla systemu Linux, a nie z wersją dla OSX - eclipse.org/mat/downloads.php
Christopher
Kiedy próbuję tego (przy użyciu ssh bash na Linuksie), natychmiast kończy się niepowodzeniem z komunikatem „Nie można zainicjować GTK +”. Wygląda więc na to, że (obecna wersja, 15.04.2016) nadal myśli, że komunikuje się z interfejsem użytkownika (?).
Charles Roth
2
Hmm, nowsze wersje ParseHeapDump.sh chcą bezpośrednio uruchamiać ./MemoryAnalyzer. Eksperymentuję z uruchomieniem launchera bezpośrednio w Javie, jak na razie wydaje się działać, np. Java -Xmx16g -Xms16g -jar plugins / org.eclipse.equinox.launcher_1.3.100.v20150511-1540.jar -consoleLog -consolelog -application org.eclipse.mat.api.parse "$ @"
Charles Roth
Wygląda na to, że możesz go używać na OS X, pobierając wersje Linux i OSX, a następnie skopiuj ParseHeapDump.sh do tego samego katalogu, co plik MemoryAnalyze (w moim przypadku ~ / Downloads / mat.app / Contents / MacOS) i zmodyfikuj i uruchom go tam. Albo oczywiście uruchom go na jakimś zdalnym serwerze przez SSH :)
rogerdpack
Otwarto zrzut sterty o pojemności 2 GB za pomocą interfejsu GUI Eclipse Memory Analyzer przy użyciu nie więcej niż 500 MB pamięci. Pliki indeksu były tworzone w locie podczas otwierania pliku (trwało to ~ 30 sekund). Może ulepszyli narzędzie. Jest to wygodniejsze niż kopiowanie dużych plików w tę iz powrotem, jeśli naprawdę działa w ten sposób. Niewielkie zużycie pamięci nawet bez narzędzi konsoli to dla mnie duży plus. Ale szczerze mówiąc, nie próbowałem tego z naprawdę dużymi zrzutami (50+ GB). Bardzo interesujące, ile pamięci potrzeba do otwierania i analizowania tak dużych zrzutów za pomocą tego narzędzia.
Ruslan Stelmachenko
6

Przyjęta odpowiedź na to powiązane pytanie powinna stanowić dobry początek dla Ciebie (używa aktualnych histogramów jmap zamiast zrzutów sterty):

Metoda znajdowania wycieku pamięci w dużych zrzutach sterty Java

Większość innych analizatorów sterty (ja używam IBM http://www.alphaworks.ibm.com/tech/heapanalyzer ) wymaga co najmniej procentu pamięci RAM więcej niż sterta, jeśli oczekujesz ładnego narzędzia GUI.

Poza tym wielu programistów stosuje alternatywne podejścia, takie jak analiza stosu na żywo, aby zorientować się, co się dzieje.

Chociaż muszę zapytać, dlaczego twoje stosy są tak duże? Wpływ na alokację i wyrzucanie elementów bezużytecznych musi być ogromny. Założę się, że duży procent tego, co jest w twojej stercie, powinien być faktycznie przechowywany w bazie danych / trwałej pamięci podręcznej itp.

Michael
źródło
5

Proponuję wypróbować YourKit. Zwykle potrzebuje trochę mniej pamięci niż rozmiar zrzutu sterty (indeksuje go i używa tych informacji do pobrania tego, co chcesz)

Peter Lawrey
źródło
4

Jeszcze kilka opcji:

Ta osoba http://blog.ragozin.info/2015/02/programatic-heapdump-analysis.html

napisał niestandardowy analizator sterty Netbeans, który po prostu ujawnia interfejs „stylu zapytania” poprzez plik zrzutu sterty, zamiast faktycznie ładować plik do pamięci.

https://github.com/aragozin/jvm-tools/tree/master/hprof-heap

Chociaż nie wiem, czy „jego język zapytań” jest lepszy niż OQL zaćmienia, o którym mowa w zaakceptowanej odpowiedzi tutaj.

Mówi się również, że JProfiler 8.1 (499 USD za licencję użytkownika) jest w stanie przemierzać duże stosy bez zużywania dużych pieniędzy.

rogerdpack
źródło
Właściwie działa na dużym wysypisku, w przeciwieństwie do powiedzmy github.com/on-site/fasthat . Miły!
Jesse Glick
4

Pierwszy krok: zwiększ ilość pamięci RAM, którą przydzielasz do MAT. Domyślnie to niewiele i nie można otworzyć dużych plików.

W przypadku korzystania z MAT na MAC (OSX) będziesz mieć plik MemoryAnalyzer.ini w MemoryAnalyzer.app/Contents/MacOS. Nie udało mi się wprowadzić poprawek do tego pliku i kazać im „wziąć”. Zamiast tego można utworzyć zmodyfikowane polecenie uruchamiania / skrypt powłoki na podstawie zawartości tego pliku i uruchomić je z tego katalogu. W moim przypadku chciałem sterty 20 GB:

./MemoryAnalyzer -vmargs -Xmx20g --XX:-UseGCOverheadLimit ... other params desired

Po prostu uruchom to polecenie / skrypt z katalogu Contents / MacOS za pośrednictwem terminala, aby uruchomić GUI z dostępną większą ilością pamięci RAM.

Michael Shvets
źródło
Dzięki. DLd narzędzie dzisiaj. Próbowałem uruchomić przez 2x-klik i dało to błąd. Spojrzał na log, nie mógł utworzyć pliku danych i powiedział, że używa przełącznika. Otworzyłem pakiet .app i znalazłem MemoryAnalyzer.ini w folderze Eclipse \, a nie \ MacOS. Ah-ha! Więc rozpakowałem wszystkie pliki lokalnie i zrobiłem tak, jak sugerowałeś. Utworzyłem plik .sh w \ MacOS i przeniosłem do niego polecenia z Eclipse \ MemoryAnalyzer.ini jako płaską pojedynczą linię. Zapisany plik. Uruchomiłem plik .sh z MacOS \ w wierszu poleceń i voila, zadziałało.
Matt Campbell,
2

Niezbyt znane narzędzie - http://dr-brenschede.de/bheapsampler/ działa dobrze w przypadku dużych stert. Działa na zasadzie samplowania, więc nie musi czytać całej rzeczy, chociaż jest trochę wybredna.

Ashwin Jayaprakash
źródło
Niestety, jest napisane "powszechny problem: brak pamięci: zwiększ -Xmx do 2/3 rozmiaru zrzutu", ale przypuszczam, że jeśli masz wystarczająco dużo pamięci RAM lub możesz uruchomić go na serwerze z wystarczającą ilością pamięci, to może wystarczyć, dzięki !
rogerdpack
2

Najnowsza wersja migawki programu Eclipse Memory Analyzer umożliwia losowe odrzucanie określonego procentu obiektów w celu zmniejszenia zużycia pamięci i umożliwienia analizy pozostałych obiektów. Zobacz błąd 563960 i nocną kompilację migawek, aby przetestować tę funkcję, zanim zostanie uwzględniona w następnej wersji MAT.

user13762112
źródło
1

To nie jest rozwiązanie wiersza poleceń, ale lubię narzędzia:

Skopiuj zrzut sterty na serwer wystarczająco duży, aby go hostować. Bardzo możliwe, że można użyć oryginalnego serwera.

Wejdź na serwer przez, ssh -Xaby zdalnie uruchomić narzędzie graficzne i użyj jvisualvmz katalogu binarnego Java, aby załadować .hprofplik zrzutu sterty.

Narzędzie nie wczytuje od razu całego zrzutu sterty do pamięci, ale ładuje części, gdy są potrzebne. Oczywiście, jeśli wystarczająco rozejrzysz się po pliku, wymagana pamięć w końcu osiągnie rozmiar zrzutu sterty.

kap
źródło
0

Spróbuj użyć jprofilera, działa dobrze w analizie dużego pliku .hprof, próbowałem z plikiem o rozmiarze około 22 GB.

https://www.ej-technologies.com/products/jprofiler/overview.html
Selvam M.
źródło
0

Natknąłem się na ciekawe narzędzie o nazwie JXray. Zapewnia ograniczoną licencję próbną. Okazało się, że bardzo przydatne jest znajdowanie wycieków pamięci. Możesz spróbować.

Sankar Natarajan
źródło