Używam systemu kompilacji. Kiedyś korzystaliśmy z kolektora CMS, ale zaczęliśmy cierpieć przy bardzo długich pełnych cyklach GC, przepustowość (czas nie robiący GC) wynosiła około 90%. Dlatego zdecydowałem się przejść na G1 z założeniem, że nawet jeśli będę miał dłuższy ogólny czas GC, przerwy będą krótsze, co zapewni wyższą dostępność. Pomysł ten wydawał się działać jeszcze lepiej niż oczekiwałem, nie widziałem pełnej GC przez prawie 3 dni, przepustowość wyniosła 97%, ogólna wydajność GC była znacznie lepsza. (Wszystkie screeny i dane dostał od GCViewer)Przerwy GC stają się naprawdę długie po kilku dniach.
Do tej pory (dzień 6). Dzisiaj system po prostu poszedł berzerk. Stara powierzchnia wykorzystywana jest zaledwie w 100%. Widzę Pełna GC wywołał niemal każde 2-3 minut lub tak, to:
Old wykorzystania przestrzeni:
rozmiar Heap jest 20G (128g Ram łącznie). Flagi, których obecnie używam to:
-XX:+UseG1GC
-XX:MaxPermSize=512m
-XX:MaxGCPauseMillis=800
-XX:GCPauseIntervalMillis=8000
-XX:NewRatio=4
-XX:PermSize=256m
-XX:InitiatingHeapOccupancyPercent=35
-XX:+ParallelRefProcEnabled
oraz rejestrowanie flag. Czego mi się wydaje brakować to: -XX:+ParallelGCThreads=20
(Mam 32 procesory), domyślnie powinienem być 8. Przeczytałem też od Oracle, że sugeruje się, aby mieć -XX:+G1NewSizePercent=4
dla sterty 20G, domyślnie powinno być 5.
Używam 64-bitowy serwer Java HotSpot (TM) VM 1.7.0_76, Oracle Corporation
Co byś zasugerował? Czy mam oczywiste błędy? Co zmienić? Czy robię zachłanność, dając Java tylko 20G? Założeniem jest tutaj, że nadanie jej zbyt dużej ilości oznaczałoby dłuższą GC, ponieważ po prostu więcej jest do czyszczenia (chłopska logika).
PS: Aplikacja nie jest moja. Dla mnie jest to produkt pudełkowy.
Wydaje mi się, że w twoim oprogramowaniu jest jakiś wyciek pamięci, który powoli zużyje dostępną przestrzeń sterty, czyniąc pracę GC coraz trudniejszą z biegiem czasu. Tak więc rozwiązania nie należy przeszukiwać w algorytmie GC ani w ustawieniach sterty (która ostatecznie zostanie wypełniona bez względu na jej rozmiar). Musisz naprawić swoje oprogramowanie lub żyć z tym, że musisz je restartować co jakiś czas. Co ciekawe, wygląda na to, że Twoja kupa nie wypełni się całkowicie, powodując awarię programu, więc może po prostu nie mam racji. –
Powinieneś wkleić dziennik GC wydrukowany z '-XX: + PrintGCDetails -XX: + PrintGCTimeStamps -XX: + PrintAdaptiveSizePolicy -Xloggc:', będzie to bardziej przydatne dla zrozumienia decyzji G1. Jeśli możesz wypróbować java 8, od tego czasu G1GC przeszedł wiele zmian. Wiele jego heurystyki zostało poprawionych, a niektóre wąskie gardła usunięte. IIRC w 7 istnieje kilka przypadków, w których G1 może sortować "malować się w rogu" –
the8472
Znalazłem rozwiązanie, system pozwala również użytkownikom na wykonywanie niestandardowych skryptów podczas procesu kompilacji. Po (bardzo długim) badaniu okazało się, że jeden użytkownik ciągle wykonuje skrypt, który nie zwalniał pamięci, powodując, że linia bazowa sterty stale rośnie, stąd cykl GC wydawany jest coraz rzadziej w każdej turze. –