Как да намалим конкурентния java отказ и прекомерен режим gc
В Java едновременният отказ на режим означава, че конкурентният колектор не е успял да освободи достатъчно място в паметта от постоянния и постоянния вид и трябва да се откаже и да остави gc напълно да спре gc на света. крайният резултат може да бъде много скъп.

Разбирам тази концепция, но никога не съм имал добро изчерпателно разбиране за А) какво може да причини едновременно неуспех и Б) Какво е решението ?.
Този вид неяснота ме кара да пиша/отстранявам код без твърде много предложения и често ми се налага да пазарувам около тези флагове за изпълнение от Foo до Bar без конкретна причина, просто трябва да опитам.
Бих искал да науча от разработчиците тук какъв е вашият опит? Ако срещнете проблем с производителността, каква е причината и как подходите към него?
Ако имате препоръки за кодиране, моля, не бъдете твърде общи. Благодаря!
4 отговора
Първото нещо за CMS, което научих, е, че се нуждае от повече памет от останалите колектори, около 25-50% повече е добра отправна точка. Това ви помага да избегнете фрагментация, тъй като CMS не извършва уплътняване, като спиране на глобалното събиране. Второ, правете неща, които помагат на сметосъбирача; Integer.value Вместо новия Integer, отървете се от анонимните класове, уверете се, че вътрешните класове нямат достъп до недостъпни неща (частни във външния клас). Колкото по-малко боклук, толкова по-добре. FindBugs и не игнорирането на предупрежденията ще помогне много в това.
Що се отнася до настройката, установих, че трябва да опитате няколко неща:
Казва на JVM да използва CMS в жанра.
Правилен размер на купчината: -Xmx2048m -Xms2048m Това пречи на GC да прави неща като увеличаване и намаляване на купчината.
Използвайте паралелно вместо серийната колекция в по-младото поколение. Това ще ускори вашите малки колекции, особено ако имате много голям млад пол. Голямо младо поколение обикновено е добро, но не надвишава половината от стария пол.
задайте броя нишки, които CMS ще използва, когато прави неща, които могат да се правят паралелно.
-XX: + CMSParallelRemarkEnabled забележката е серийна по подразбиране, това може да ви ускори.
-XX: + CMSIncrementalMode позволява на приложението да работи по-дълго, като превключва GC между фазите
-XX: + CMSIncrementalPacing позволява на JVM да променя промяната на честотата на събиране с течение на времето
-XX: CMSIncrementalDutyCycleMin = X Минимално количество време, прекарано в GC
-XX: CMSIncrementalDutyCycle = X Започнете с GC този% от времето
-XX: CMSIncrementalSafetyFactor = X
Открих, че обикновено можете да получите кратки периоди на почивка, ако ги настроите така, че винаги да се събират. Тъй като по-голямата част от работата се извършва паралелно, ще достигнете обикновено предвидими почивки.
-XX: CMSFullGCsBeforeCompaction = 1
Това е много важно. Той казва на CMS колектора винаги да попълва колекцията, преди да започне нова колекция. Без това можете да влезете в ситуацията, когато хвърлите много работа и да започнете отново.
По подразбиране CMS ще позволи на вашия PermGen да расте, докато не убие приложението ви след няколко седмици. Това спира. Вашият PermGen би се увеличил само ако използвате Reflection или неправилно използвате String.intern или направите нещо нередно с зареждащ клас или нещо подобно.
На оцелелия може да се играе и в зависимост от това дали имате обекти с дълъг или кратък живот и колко е да копирате обекта между пространствата за оцеляване, с които можете да живеете. Ако знаете, че всичките ви обекти ще останат наоколо, можете да конфигурирате нулеви пространства за оцеляване и всичко, което ще оцелее в една млада жанрова колекция, ще бъде веднага на разположение.
Неуспехът в едновременен режим може да бъде избегнат чрез увеличаване на броя на генерираните филиали или иницииране на събиране на CMS до по-малък капацитет чрез задаване на CMSInitiatingOccupancyFraction на по-ниска стойност
Ако обаче в приложението ви има изтичане на памет, просто купувате време.
Ако имате нужда от бързо рестартиране и възстановяване и предпочитате "бърз" подход, бих препоръчал изобщо да не използвате CMS. Бих се бил с '-XX: + UseParallelGC'.
Паралелният събирач на боклук (UseParallelGC) изхвърля изключение извън паметта, ако е прекалено много време е събрал малко количество от купчината. За да избегнете това изключение, можете да увеличите размера на сметището. Можете също така да зададете параметрите -XX: GCTimeLimit = ограничение по време и -XX: GCHeapFreeLimit = пространство-ограничение
Понякога OOM доста бързо и беше убит, понякога страдаше дълго време (последният период беше над 10 часа).
Струва ми се, че изтичането на памет е в основата на вашите проблеми.
Неуспехът на CMS няма да причини (както разбирам) OOM. По-скоро се случва грешка в CMS, защото JVM трябва да направи твърде много колекции твърде бързо и CMS не може да се справи. Ситуация, при която много цикли на събиране се случват за кратък период от време, е когато сметището ви е почти пълно.
Наистина дългото време за шум звучи странно. но теоретично е възможно колата ви да се движи ужасно. Дългият период на повтаряне на CG обаче е напълно правдоподобен, ако сметището ви е почти пълно.
Можете да конфигурирате GC да пада, когато дъмпът е 1) в пълен размер и 2) все още близо до пълен, след като завършите пълния GC. Опитайте да направите това, ако още не сте го направили. Това няма да реши проблемите, но поне вашият JVM ще получи OOM бързо, което ви позволява да рестартирате и възстановите услугата по-бързо.
РЕДАКТИРАНЕ - опцията да направите това е -XX: GCHeapFreeLimit = nnn, където nnn е число между 0 и 100, даващо минималния процент от купчината, който трябва да бъде свободен след GC. По подразбиране е 2. Опцията е изброена в подходящо озаглавената страница „Най-пълният списък с опции -XX за Java 6 JVM“. (Там са изброени много опции -XX, които не се появяват в документацията на Sun. За съжаление страницата предоставя малко подробности за това какво всъщност правят опциите.)
Вероятно трябва да започнете да търсите дали приложението/webapp има изтичане на памет. Ако е така, проблемите ви няма да изчезнат, освен ако не бъдат открити и отстранени. В дългосрочен план боравенето с опциите на Hotspot GC няма да поправи изтичането на памет.