PermGen space - jaki powinien być właściwy rozmiar?

0

Witam,
Jak wiadomo PermGen to przestrzeń, w której przechowuje się wartości klas po uruchomieniu aplikacji. Jaki powinien być rozmiar PermGen, gdy ustawiam -Xms i -Xms na 2000 MB?

Czy mogę bezpiecznie zwiększyć ten rozmiar np. do 1000 MB? Domyślnie z tego co widzę jest to 192 MB. A po kilku deployach zdarza się zobaczyć błąd PermGenSpace.

Jaki jest wpływ tych parametrów na pracę garbage collectora?

Pozdrawiam,

0

Jak ci sie aplikacja wysypuje bo permgen się kończy to znaczy ze spieprzyłeś tą aplikację i to dość mocno. Chyba ze mówisz o systemie na kilka milionów linii kodu, dziesiatki tysięcy klas, która ma load tysięcy użytkowników na godzinę. Ale szczerze wątpię....
PermGen to jest coś co przechowuje definicje klas, które dużo nie zajmują... Najpewniej masz wyciek pamięci na przykład bo tworzysz dziesiątki obiektów proxy (używasz cgliba? lambda4j?) albo używasz jvm internal cache (np. String.intern()) i go wypychasz niepotrzebnie.
PermGen jest permanentny i nie wpływa w ogóle na GC. To co ta siedzi, siedzi tam cały czas.

A parametr Xms i Xmx nie mają (prawie) nic wspólnego z PermGenem bo są zwiazane z heapem...

0

Dzięki za odpowiedź.

Owszem, aplikacja jest niezle spaprana w kwestii JPA: zostalo tam ustawione RESOURCE_LOCAL i nie ma obslugi transakcji przez kontener (przez poprzednich programistow, my to rozwiajmy dalej). Nie udalo sie tego sensownie zrefaktoryzowac, ale nie ma tam transakcji rozproszonych, wiec az tak nie boli. Ja oddzidziczylem ta aplikacje, zrefaktoryzowalem i podnioslem z JEE 5.0 do 7.0. W tej chwili jest juz lepiej, ale musze pracowac ze starym kodem z duza iloscia WTFow. Ale za kazdym razem EntityManagery tworzone z fabryk sa zamykane, wiec leaka w JPA byc nie powinno.

To się dzieje wtedy, gdy idzie dużo deployów w krótkim czasie. Po pojedynczym deployu jest spoko. Projekt jest dosyć duży, miliona linii kodu nie ma, ale w przyszłości na pewno będzie. Jest to około 80 tabel w SQL. Nigdy nie było tak, aby wysypało mi się po pierwszym, ale po kilku krótkich owszem, zdarza się to często. Wychodzi na to, że szybkie deploye dużego projektu zabijają classloader. Dlaczego tak się dzieje, skoro deploy wykonuje undeploy, który powienien wyczyścić? Jak szukać tego leaka, z użyciem darmowych narzędzi?

Nie używam bibliotek, o których wspomniałeś. Za to JPA, IceFaces 1.8 (stary projekt), JSF 2.2, Spring Security i JasperReports i pare innych bibliotek.

http://stackoverflow.com/questions/7683434/permgen-space-error-glassfish-servero,

Z tego co widzę użytkownicy GlassFisha często tego doświadczają:
https://java.net/jira/browse/GLASSFISH-20732

Czy możliwe, że to defekt serwera aplikacji?

Jak najprościej szukać leaków?

0
  1. A zabijasz serwer przed redeployem? Bo jeśli nie, to możliwe że żeby "przyspieszyć" deploy kontener nie usuwa starych definicji tylko dorzuca nowe i stąd problem że po kilku deployach kończy się permgen. IntelliJ ma taką opcję żeby deployować rozpakowanego wara i wtedy można często robić "hot-swap" klas bez konieczności budowania wara od nowa i deployowania od nowa.
  2. VisualVM, JProfiler
0

Odpalasz na JVM 32-bitowej czy 64-bitowej? Na 32 bitach może po prostu zabraknąć przestrzeni adresowej.

Może włączenie odładowywania starych klas pomoże? http://stackoverflow.com/questions/3334911/what-does-jvm-flag-cmsclassunloadingenabled-actually-do

0

@Wibowit
Mam 64 bit JVM. Spróbuje tego rozwiązania jak tylko będę miał dostęp do maszyny z projektem.

BTW. Co sądzicie o ustawieniu takiego samego min jak i max heap size? Czytałem, że to nie jest zły pomysł, bo zmiana heap w przypadku dynamicznego zmieniania rozmiaru sterty wymaga pełnego cyklu garbage collectora, co bywa źródłem niezłych lagów. I tam gdzie lagi są nieporządane warto dać taki sam max jak i min heap size. Prawda?

0

Prawda, ale nie cała prawda. Tak jest przy standardowym GC i przy CMS.
Ale już G1 bardzo ładnie radzi sobie ze zmienianiem rozmiaru sterty bez pełnego GC.

0

Hot deploymentu nigdy nie powinno się stosować na produkcji.

Zbyt łatwo można nieświadomie doprowadzić do sytuacji, w której klasy nie mogą być usunięte, gdyż gdzieś jest referencja do jakiejś instancji.

Wystarczy, np. zapamiętać jedną instancję klasy w ThreadLocal i już przy redeployu nie zostanie usunięta z pamięci ta klasa oraz inne ładowane przez ten sam ClassLoader.

Błąd nie musi być w Twojej aplikacji. Wystarczy, że jedna z bibliotek, której używasz ma coś takiego (np. Spring https://jira.springsource.org/browse/SPR-9274 )

http://stackoverflow.com/questions/12717895/memory-leak-on-stop-or-redeploy-spring-3-1-2-hibernate-4-1-0-spring-data-jpa

Czy mogę bezpiecznie zwiększyć ten rozmiar np. do 1000 MB? Domyślnie z tego co widzę jest to 192 MB. A po kilku deployach zdarza się zobaczyć błąd PermGenSpace.

To zależy, ile masz całej pamięci przydzielonej Javie. Permgen raczej nie powinien przekraczać 20% pamięci.

1 użytkowników online, w tym zalogowanych: 0, gości: 1