2011-09-13 13 views
19

wiem, że nie jest to „najlepsze praktyki”, ale chciałbym wiedzieć, czy mogę automatyczny restart tomcat jeśli wdrożony aplikacja zgłasza OutOfMemory wyjątekMogę automatyczny restart tomcat JVM na z wyjątkiem pamięci

+0

Prawidłowa odpowiedź brzmi, że autorzy Java nigdy nie powinni odrabiać możliwości OutOfMemoryErrors. Powinny zawsze zabijać maszynę wirtualną, a skrypt lub menedżer obsługiwałby ponowne uruchomienie. Co więcej, Tomcat również nie powinien ich łapać. – mikevdg

Odpowiedz

23

Można spróbować użyć opcji OnOutOfMemoryError JVM

-XX:OnOutOfMemoryError="/yourscripts/tomcat-restart" 

Możliwe jest również, aby wygenerować zrzut sterty dla późniejszej analizy:

-XX:+HeapDumpOnOutOfMemoryError 

być ostrożnym przy połączeniu tych dwóch opcji. Jeśli wymusisz zabicie procesu w "tomcat-restart", zrzut sterty może nie być kompletny.

+0

Rzeczywiście dostaję błąd permen z powodu przecieku classloader Zgaduję. Czy ta sama flaga działa również w tym scenariuszu? – Abe

+2

Tak , będzie działać również na błąd przestrzeni permgen, – Dan

+0

Ale jaka jest zawartość "tomcat-restart"? Czy to po prostu shutdown.bat, startup.bat? – Gullbyrd

5

nie łatwo , a zdecydowanie nie przez JVM, która właśnie przeżyła wyjątek z pamięci. Najlepszym rozwiązaniem byłoby połączenie monitora statusu tomcat ze skryptami cron lub powiązanymi skryptami administratora systemu; coś, aby sprawdzić stan serwera i automatycznie zatrzymać i ponownie uruchomić usługę, jeśli się nie udało.

+0

Wygląda na to, że to ogólny konsensus ... :( – Abe

4

Generalnie nie. Maszyna wirtualna jest złym stanem i nie można jej całkowicie zaufać.

Zazwyczaj można użyć konfigurowalnego procesu otoki, który uruchamia i zatrzymuje "prawdziwą" maszynę wirtualną serwera. Przykładem Pracowałem już z jest „Java Usługa wrapper” z Tanuki Software http://wrapper.tanukisoftware.com/doc/english/download.jsp

Wiem, że są inni.

Po pierwsze, aby chronić się przed OOM, istnieją sposoby na instrumentowanie nowoczesnych maszyn wirtualnych za pomocą komponentów bean interfejsu w celu sprawdzania statusu sterty i innych struktur pamięci. Można ich użyć do, powiedzmy, ostrzeżenia w dzienniku lub e-mailu, jeśli niektóre operacje specyficzne dla aplikacji przesuwają określone ograniczenia.

+1

Owijka Tanuki jest zdecydowanie najlepszym sposobem na przejście –

+0

+1 w moim przypadku skrypt działał jako część XX: OnOutOfMemoryError = "/ yourscripts/tomcat-restart nie mógł przynieś tomcat kopię zapasową – Tomasz

+0

Theres's także YAJSW twierdzi, że jest w pełni kompatybilny z JSW. Możesz spróbować, jeśli pasuje do twoich potrzeb (to open source), ale z mojego doświadczenia wynika, że ​​JSW jest warta swojej ceny –

6

Wiem, że to nie jest to, o co prosiłeś, ale czy próbowałeś przeszukać zwałowisko sterty, aby zobaczyć, gdzie może wyciekać pamięć?

kilka bardzo przydatnych narzędzi do śledzenia wycieków pamięci:

jdk/bin/jmap -histo:live pid 

To daje histogram wszystkich żywych obiektów obecnie w JVM. Szukaj dowolnego dziwnego obiektu. Będziesz musiał znać swoją aplikację całkiem dobrze, aby móc określić, jakie liczby obiektów są dziwne.

jdk/bin/jmap -dump:live,file=heap.hprof pid 

Spowoduje to zrzucenie całego stosu maszyny JVM identyfikowanej przez pid. Następnie możesz użyć wspaniałego Eclipse Memory Analyzer, aby sprawdzić i sprawdzić, kto trzyma się odniesień do twoich obiektów. Twoimi dwoma największymi przyjaciółmi w Eclipse Memory Analyzer są gram histo i right click -> references -> exclude weak/soft references, aby zobaczyć, co jest referencją do twojego obiektu.

jconsole to oczywiście kolejne dobre narzędzie.

+0

Dzięki za Polecenie hprof, dobrze mieć to w arsenale ... :) Używam visualvm do takich rzeczy normalnie – Abe

0

Co powiesz na coś takiego? -XX:OnOutOfMemoryError="exec \`ps --no-heading -p $$ -o cmd\`"

1

Niestety, po zabiciu procesu Java. Twój skrypt zachowa odniesienie do portów tomcat 8080 8005 8009 i nie będziesz mógł go uruchomić ponownie z tego samego skryptu. Jedyny sposób, w jaki działa to dla mnie:

-XX: OnOutOfMemoryError = "kill -9% p", a następnie kolejny cron lub monit lub coś podobnego, aby zapewnić ponowne uruchomienie tomcat.

% p jest faktycznie paczką JVM, czymś, co zapewnia JVM.

Powiązane problemy