2010-12-30 3 views
53

To pytanie jest dla każdego, kto kiedykolwiek badanego przycisk „Znajdź przecieki” w menedżerze Tomcat, ale niektóre wyniki tak:Czy istnieje sposób na uniknięcie wycieków pamięci w systemie Tomcat?

następujące aplikacje internetowe zostały zatrzymane (reloaded, odinstalowana), ale ich zajęcia z ostatnich biegnie nadal ładowane do pamięci, powodując wyciek pamięci (użyć profilera do potwierdzenia):
/nieszczelny-app-name

jestem przy założeniu ma to coś wspólnego z tym „Perm Gen przestrzeni” błąd często pojawiający się przy częstych przeniesieniach.

To, co widzę w jconsole podczas wdrażania, to to, że moje załadowane klasy mają wartość od około 2k do 5k. Wtedy uważasz, że przesunięcie powinno spowodować powrót do 2k, ale pozostanie przy 5k.

Próbowałem zostały również za pomocą następujących opcji JVM:

-XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:+CMSPermGenSweepingEnabled

ja widziałem bardzo niewielkie spadki w ilości miejsca Perm Gen używane ale nie to, czego się spodziewałem i załadowane klasy nie liczy upuszczać.

Więc czy istnieje sposób, aby skonfigurować Tomcat lub zaprojektować aplikację, aby lepiej się rozładowała podczas wycofywania? Czy utknęliśmy w ponownym uruchomieniu serwera po kilku poważnych sesjach debugowania?

Tomcat wersja wyjściowa:

wersja Server: Apache Tomcat/6.0.29
Server budowy: 19 lipiec 2010 1458
numer serwera: 6.0.0.29
Nazwa OS: Windows 7
OS wersja: 6.1
Architektura: x86
JVM wersja: 1.6.0_18-B07
JVM Producent: Sun Microsystems Inc.

Aktualizacja:

Dzięki odpowiedź celias' postanowiłem zrobić trochę więcej kopanie i myślę, że ustaliła sprawcę, aby być w mojej aplikacji dzięki CXF, wiosną i JAXB.

Po tym, jak nauczyłem się profilować aplikację Java, wskazałem profilera na Tomcat i zrobiłem kilka zrzutów sterty i migawek, aby zobaczyć, jak wyglądały obiekty i klasy w pamięci. Odkryłem, że niektóre wyliczenia z mojego schematu XML używanego w moich wygenerowanych klasach CXF/JAXB (wsdl2java) utrzymywały się po wycofaniu. Według mojego zrzutu stosu wygląda to tak, jakby obiekty były powiązane z mapą. Zastrzeżenie: Przyznaję, że wciąż jestem trochę zielony z profilowaniem i śledzenie drzewa wywołania obiektu może być trudne w Javie.

Należy również wspomnieć, że nie skorzystałem nawet z usługi, po prostu ją wdrożono, a następnie ją usunąłem. Same obiekty wydawały się być ładowane poprzez odbicie zainicjowane od wiosny po wdrożeniu. Uważam, że podążałem za konwencją dotyczącą utworzenia usługi CXF na wiosnę. Więc nie jestem w 100% pewny, czy to jest Spring/CXF, JAXB, czy błąd odbicia.

Na marginesie: przedmiotowa aplikacja jest usługą sieciową wykorzystującą Spring/CXF, a XML jest raczej złożonym schematem (rozszerzenie NIEM).

Odpowiedz

15

Jeśli chcesz się upewnić, aby nie powodować przecieki trzeba wykonać następujące czynności:

  • Upewnij się, że aplikacja internetowa nie używa żadnych klas Java, które są w pojemniku internetowych współdzielonych bibliotek. Jeśli posiadasz biblioteki współdzielone, upewnij się, że nie ma silnych odniesień do obiektów w tych bibliotekach. Unikaj używania zmiennych statycznych, szczególnie w obiektach java, takich jak HashTable, Zestawy itp. Jeśli musisz, upewnij się, że wywołasz polecenie remove aby zwolnić obiektów z mapami, list ...

Tutaj jest również dobry artykuł na ThreadLocal i MemoryLeaks - http://blog.arendsen.net/index.php/2005/02/22/threadlocals-and-memory-leaks-revisited/

+0

dobrych informacji! Próbowałem zrobić bardzo prostą aplikację bez żadnych bibliotek stron trzecich lub udostępnionych i nie widziałem tych samych objawów, które opisałem powyżej. Jedynym problemem jest to, że aplikacja "real world" prawdopodobnie będzie miała jakieś wycieki pamięci gdzieś z wykorzystaniem bibliotek innych firm. Sądzę więc, że wszystko sprowadza się do deweloperów gdzieś po linii. Na pewno wszyscy moglibyśmy ulepszyć: Tomcat, nasze aplikacje, biblioteki ... – waltwood

+1

Czy ktoś wie więcej na temat wpływu generowania kodu bajtowego, ponieważ jest używany przez wiele serializatorów XML, Hibernate, Tapestry? Czy te biblioteki są poprawnie rozładowywane? – Codo

+0

OK, pochopnie stwierdziłem, że nie widzę tych samych objawów. Może moja aplikacja testowa była zbyt mała, by ją zauważyć. Przetestowałem aplikację Tomcat Examples i ponownie zobaczyłem, że PermGen zapełnia się, a załadowane klasy nigdy nie powróciły do ​​linii bazowej po wycofaniu. Rozumiem, że PermGen służy do przechowywania metadanych dotyczących załadowanych klas. Więc sądzę, że przeniesienie powinno spowodować, że Tomcat usunie referencje klas dla aplikacji, a GC powinien je wyczyścić i poprawić ich metadane? Nawet jeśli moje zajęcia zawierają silne odniesienia do innych klas, czy nie powinny one umrzeć, gdy Tomcat rozładuje klasy rodziców? – waltwood

6

Tomcat 7 ma przynieść ulepszenia w tym obszarze. Zobacz Features of Apache Tomcat 7, rozdział zatytułowany Nie więcej wycieków!

Uważają, że mogą teraz poradzić sobie z wieloma wyciekami pamięci spowodowanymi przez aplikacje internetowe. Niestety nadal jest w wersji beta.

Poza tym mogę powiedzieć, że zrobiłem to samo i nie znalazłem rozwiązania. Wdrażanie zwykle wymaga ponownego uruchomienia Tomcata. Nie mam pojęcia, kto jest winowajcą: moja aplikacja internetowa, Tomcat, Hibernate, Tapestry lub kilka z nich.