Jak niezawodnie przyjmować zrzuty Java?

9

Mój zespół napotyka trudności podczas próby wykonania dobrych zrzutów sterty wywołanych przez błędy OutOfMemoryErrors. Z konkretnych powodów obecnie wykonujemy zrzuty z wywołaniem jmap ze skryptu bash zamiast używania flagi HeapDumpOnOutOfMemoryError. Używamy 64-bitowej JVM 1.6 z wielkością sterty około 3 GB. Nasze zrzuty sterty zawodzą w 90% przypadków (oszacowanie).

Czy jest coś, co możemy zrobić, aby zwiększyć nasze szanse na uzyskanie czystego zrzutu stosu, którego możemy użyć do rozwiązania problemów z pamięcią? Czytałem, że jmap miał poważne problemy w Javie 1.4, ale te problemy powinny być w większości teraz rozwiązane.

karlcyr
źródło
4
Nominuję to pytanie do „najbardziej niezamierzenie obrzydliwie brzmiących”.
phoebus
1
Hah ... Myślałem o celowo obrzydliwie brzmiącym, ale jestem tu nowy i nie byłem pewien, jak społeczność to odbierze :).
karlcyr

Odpowiedzi:

7

Jaki jest twój system operacyjny? (Nie mogę dodawać komentarzy).

W przypadku systemu Solaris uzyskujemy lepsze wyniki, najpierw wymuszając zrzut gcore <pid>pamięci ( ), a następnie dołączając plik jmap do pliku zrzutu pamięci ( jmap -heap:format=b <path to java bin> <path to core>)

gcoreto narzędzie * nix do generowania obrazu działającego programu. Zobacz link .

fglez
źródło
próbowałem go z gdb na Linuksie i działa świetnie.
Christian
który JDK ma „gcore”? mine, Sun 32-bitowy jdk dla Linuksa 1.6.0.20 nie ma go.
djangofan 17.03.11
Edytowane z wyjaśnieniem gcore.
fglez 18.03.11
2

mamy plik JSP, który wysyła zapytanie do ManagementFactory.getThreadMXBean () i generuje raport. Może się nie przydać, gdy aplikacja ulegnie awarii, ale jeśli będziesz sondować co około minutę, zorientujesz się, co się dzieje.

Więcej informacji tutaj.

rytis
źródło
2

możesz monitorować swoją aplikację przez jmx z zewnątrz. gdy znasz jakieś metryki wskazujące na nadchodzącą pamięć OutOfMemory, możesz uruchomić jmap przed zgłoszeniem wyjątku.

chrześcijanin
źródło
Dzięki Christian- czy jmap jest bardziej wiarygodny przed zgłoszeniem błędu?
karlcyr
jmap nadal potrzebuje trochę czasu, aby uzyskać zrzut stosu. ale dostaniesz pełny zrzut, o ile twój jvm / tomcat jest w większości odpowiedzialny.
Christian
Myślę, że najczystszym i najłatwiejszym narzędziem do tego jest „Visual VM”. Może być poza zakresem, ale stworzenie niestandardowej wtyczki dla VisualVM, która wykrywa warunek i wykonuje automatyczne zrzuty z VisualVm, byłoby niesamowitym IMHO.
djangofan,
2

Dziękujemy wszystkim za sugestie.

Skończyło się na tym, że napisaliśmy skrypt, aby aktywnie monitorować dzienniki czyszczenia pamięci. Z naszego doświadczenia wynika, że ​​pełne GC są zawsze poprzedzone OOM, więc nasz skrypt wykrywa to zdarzenie, z wdziękiem usuwa serwer z puli równoważenia obciążenia i wymusza zrzut sterty. To znacznie zwiększyło naszą skuteczność.

karlcyr
źródło
2

To dość stare pytanie, ale dam odpowiedź z nadzieją, że ktoś może uznać to za przydatne.

jmap ma opcję -F (siła). W przeszłości okazało się, że to nie działa tak dobrze. Jeśli chcesz użyć opcji -F, zaleciłbym również podanie katalogu java.io.tmp jako części polecenia jmap. Wystąpił problem z JVM w wersji 1.6.22, w którym narzędzie jmap nie działało poprawnie z powodu ustawienia katalogu tymczasowego.

Możesz także spróbować zrobić zrzut podstawowy za pomocą gdb. Po uzyskaniu rdzenia, jmap może przekonwertować rdzeń na zrzut sterty.

Nick Hristov
źródło