2012-12-05 6 views
5

Używam programu Tomcat na maszynie z 64-bitową pamięcią 4-procesorową i 32-bitową (OS to CentOS 6.3). Opcja Java, w której uruchamiam Tomcat, to: -server -Xms1024m -Xmx1024m -XX:PermSize=512m -XX:MaxPermSize=512mProgram Java (Tomcat) zatrzymuje pamięć (RES na górze)

Na początku RES ma tylko 810 MB na górze i stale rośnie. W tym okresie uruchamiam jmap -J-d64 -histo pID, aby sprawdzić stertę pamięci Java i myślę, że gc działa dobrze, ponieważ szczyt sterty wynosi 510 MB, a około 200 MB po gc. Ale gdy OZE w najlepszych wynikach 1.1g, użycie procesora przekroczy 100%, a Tomcat zawiesi się.

Używanie jstack pid do wyświetlania zrzutu, gdy użycie procesora wynosi 100%, wątek o nazwie "wątek vm" pochłania prawie 100% procesora. Przeszukałem go, to jest wątek JVM. Moje pytanie brzmi: dlaczego res rośnie, kiedy gc działa dobrze? Jak mogę rozwiązać ten problem? Dzięki.

+0

Widzę, że przyjął moją odpowiedź. Tylko z ciekawości, czy mógłbyś krótko opisać, co było przyczyną i co dokładnie pomogło? –

+0

Kiedy wątek gc zajmował więcej niż 100% procesora, pierwszą rzeczą, o której pamiętam, jest przeciek pamięci. Ale faktem jest - Xmx1024m jest zbyt mały dla mojej aplikacji ..... Popełniłem błąd :(Zwiększam pamięć do 2048m (-Xmx2048m), a OZE topu nie wzrasta, gdy jest to 1,2g ......... – ing

+1

to chyba odpowiedź na @digitaljoel jest bardziej odpowiednia do zaakceptowania –

Odpowiedz

1

Jeśli wątek do zbierania śmieci obraca się o 100%, prawdopodobnie próbuje on przeprowadzić wyrzucanie śmieci, ale żaden z obiektów nie może zostać zebrany, więc znajdujesz się w spirali śmierci kolekcji zbierającej śmieci, gdzie nadal próbuje działać, ale nie można zwolnić żadnej pamięci.

Może się tak zdarzyć, ponieważ w programie wystąpił wyciek pamięci lub po prostu nie dajesz wystarczającej ilości pamięci do obsłużenia liczby ładowanych obiektów podczas normalnego użytkowania. Wygląda na to, że masz dużo miejsca na głowę, aby zwiększyć rozmiar sterty. Może to tylko wydłużyć czas przed uderzeniem spirali śmierci, lub może doprowadzić do stanu działania. Będziesz chciał przeprowadzić test od dłuższego czasu, aby upewnić się, że nie tylko opóźnisz nieuniknione.

+0

Dzięki za odpowiedź. Polecenie pmap/top pokazuje, że pamięć ciągle rośnie, ale jmap pokazuje, że sterta wynosi około 200 MB po gc, jej szczyt to około 550 MB. Z wyjątkiem sterty, każdy inny rodzaj pamięci w java może wprowadzić wyciek? – ing

+0

sterty nadal jest około 200MB, nawet jeśli wątek gc jest w 100%? Czy możesz dołączyć jvisualvm, aby spojrzeć na wzór zbierania śmieci i przestrzeń sterty podczas uruchamiania? – digitaljoel

+0

, Zwiększam pamięć do 2048 m (-Xmx2048m), a RES topu nie zwiększa się, gdy wynosi 1,2 g. Powinienem spróbować jeszcze przed pytaniem. Dzięki za pomoc. – ing

2

Może to być przeciek permgen. Jeśli powiesz, że twój stos pozostaje w ~ 500 Mb, a -XX: MaxPermSize jest ustawiony na 512 MB, pełna permgen da ci około 1 GB użycia pamięci.

Może się zdarzyć, jeśli masz dużo (jak, wiele!) Jsps ładowanych później w cyklu życia twojego programu lub bardzo często używałeś String.intern().

Śledź ten wątek do dalszych badań: How to dump Permgen?

i ten wątek do strojenia GC zamiatać PermGen What does JVM flag CMSClassUnloadingEnabled actually do?

+0

+1 za świetne linki. – digitaljoel