Ako znížiť zlyhanie konkurencie v jave a nadmerný režim gc
V Jave zlyhanie súbežného režimu znamená, že konkurenčný zberateľ nedokázal uvoľniť dostatok pamäte permanentného a permanentného druhu a musí sa vzdať a nechať gc úplne zastaviť svet gc. konečný výsledok by mohol byť veľmi drahý.

Rozumiem tomuto konceptu, ale nikdy som dobre a komplexne nepochopil A) čo by mohlo spôsobiť zlyhanie súčasne a B) aké je riešenie ?.
Tento druh nejednoznačnosti ma vedie k tomu, aby som písal/odstraňoval problémy s kódom bez príliš veľkého množstva návrhov, a často musím tieto príznaky výkonu od Foo do Bar nakupovať bez konkrétneho dôvodu, musím sa len pokúsiť.
Chcel by som sa od vývojárov dozvedieť, aké sú vaše skúsenosti? Ak ste narazili na problém s výkonom, aká bola jeho príčina a ako ste sa k nemu postavili?
Ak máte odporúčania týkajúce sa kódovania, nebuďte príliš obecní. Vďaka!
4 odpovede
Prvá vec, ktorú som sa o CMS dozvedel, je, že potrebuje viac pamäte ako ostatní zberatelia, dobrý východiskový bod je asi o 25-50% viac. To vám pomôže vyhnúť sa fragmentácii, pretože CMS nevykonáva žiadne zhutňovanie, napríklad zastavenie globálneho zhromažďovania. Po druhé, rob veci, ktoré pomáhajú smetiarom; Integer.value Namiesto nového Integer sa zbavte anonymných tried, uistite sa, že vnútorné triedy nemajú prístup k neprístupným veciam (súkromné vo vonkajšej triede). Čím menej odpadkov, tým lepšie. FindBugs a ignorovanie varovaní v tomto veľmi pomôže.
Pokiaľ ide o ladenie, zistil som, že musíte vyskúšať niekoľko vecí:
Hovorí spoločnosti JVM, aby používala CMS v žánri, v ktorom získal honorár.
Správna veľkosť hromady: -Xmx2048m -Xms2048m To zabráni spoločnosti GC robiť veci, ako je zväčšovanie a zmenšovanie hromady.
U mladšej generácie používajte namiesto sériového zberu paralelné. To urýchli vaše menšie zbierky, najmä ak máte nastavené veľmi veľké mladé pohlavie. Veľká mladá generácia je všeobecne dobrá, ale nepresahuje polovicu starého pohlavia.
nastaviť počet vlákien, ktoré CMS použije pri paralelných činnostiach.
-XX: + Poznámka CMSParallelRemarkEnabled je predvolene sériová, čo vás môže urýchliť.
-XX: + CMSIncrementalMode umožňuje aplikácii bežať dlhšie prepínaním GC medzi fázami
-XX: + CMSIncrementalPacing umožňuje spoločnosti JVM meniť frekvenciu zberu v priebehu času
-XX: CMSIncrementalDutyCycleMin = X Minimálne množstvo času stráveného v GC
-XX: CMSIncrementalDutyCycle = X Začnite s GC v tomto% času
-XX: CMSIncrementalSafetyFactor = X
Zistil som, že vo všeobecnosti môžete získať krátke prestávky, ak ich nastavíte tak, aby sa vždy zbierali. Pretože väčšina práce sa vykonáva súbežne, dosiahnete zvyčajne predvídateľné prestávky.
-XX: CMSFullGCsBeforeCompaction = 1
Toto je veľmi dôležité. Povedá zberateľovi CMS, aby zbierku vždy dokončil pred začatím novej zbierky. Bez toho sa môžete dostať do situácie, keď vrhnete veľa práce a začnete odznova.
V predvolenom nastavení CMS nechá váš PermGen rásť, až kým vašu aplikáciu za niekoľko týždňov nezabije. Toto sa zastaví. Váš PermGen by sa zvýšil, iba ak použijete Reflection alebo nesprávne použijete String.intern alebo urobíte niečo s nakladačom tried alebo s niečím iným.
Preživší sa dá hrať aj podľa toho, či máte predmety s dlhou alebo krátkou životnosťou a koľko je to kopírovanie predmetu medzi priestormi pre pozostalých, s ktorými môžete žiť. Ak viete, že všetky vaše objekty zostanú v okolí, môžete nakonfigurovať priestory prežitia s nulovou veľkosťou a všetko, čo prežije mladú žánrovú zbierku, bude okamžite sprístupnené.
Zlyhaniu súčasného režimu sa dá vyhnúť zvýšením počtu generácií pridružených spoločností alebo spustením zberu CMS na menšiu kapacitu nastavením CMSInitiatingOccupancyFraction na nižšiu hodnotu
Ak však vo vašej aplikácii skutočne dôjde k úniku pamäte, len si kupujete čas.
Ak potrebujete rýchle reštartovanie a zotavenie a uprednostňujete „rýchly“ prístup, navrhol by som nepoužívať CMS vôbec. Bojoval by som s „-XX: + UseParallelGC“.
Paralelný zberač odpadu (UseParallelGC) vyvolá výnimku z nedostatku pamäte, ak je to nadmerné množstvo času, ktoré zhromaždilo malé množstvo z hromady. Ak sa chcete vyhnúť tejto výnimke, môžete zväčšiť veľkosť skládky. Môžete tiež nastaviť parametre -XX: GCTimeLimit = časový limit a -XX: GCHeapFreeLimit = medzerový limit
Niekedy OOM pomerne rýchlo a bol zabitý, niekedy trpel dlho (posledná perióda bola viac ako 10 hodín).
Zdá sa mi, že únik pamäte je koreňom vašich problémov.
Zlyhanie CMS nespôsobí (ako to chápem) OOM. Skôr dôjde k zlyhaniu CMS, pretože JVM musí robiť príliš veľa zbierok príliš rýchlo a CMS nestíha. Situácia, keď sa v krátkom časovom období stane veľa cyklov zberu, je vaša skládka takmer plná.
Skutočne dlhá doba šumu znie čudne. ale je to teoreticky možné, ak sa vaše auto pohybuje príšerne. Avšak dlhé obdobie opakovania CG je celkom pravdepodobné, ak je vaša skládka takmer plná.
Môžete nakonfigurovať GC, aby klesol, keď je výpis 1) v plnej veľkosti a 2) stále takmer plný po dokončení úplného GC. Skúste to urobiť, ak ste to ešte neurobili. Problémy sa nevyriešia, ale aspoň váš server JVM dostane OOM rýchlo, čo vám umožní rýchlejšie reštartovať a obnoviť službu.
vydanie - možnosť je -XX: GCHeapFreeLimit = nnn, kde nnn je číslo od 0 do 100, ktoré udáva minimálne percento haldy, ktorá musí byť po GC voľná. Predvolená hodnota je 2. Táto možnosť je uvedená na stránke s príhodným názvom „Najkompletnejší zoznam možností -XX pre Java 6 JVM“. (Je tu uvedených veľa možností -XX, ktoré sa v dokumentácii spoločnosti Sun neobjavujú. Bohužiaľ stránka poskytuje niekoľko podrobností o tom, čo tieto možnosti vlastne robia.)
Pravdepodobne by ste mali začať zisťovať, či má aplikácia/webapp úniky pamäte. Ak je to tak, vaše problémy nezmiznú, pokiaľ nebudú nájdené a opravené. Z dlhodobého hľadiska spracovanie volieb Hotspot GC neopraví úniky pamäte.