ПредишенСледващото

В тази статия, аз не бих искал да се съсредоточи върху принципа на работа на боклукчията - това е добре и ясно е описано тук: habrahabr.ru/post/112676/. Искам повече отидете на практическите основи и количествени характеристики за конфигуриране на събиране на боклука в JVM - и да се опитаме да разберем как тя може да бъде ефективна.

Количествени характеристики на оценка на ефективността на GC


Разгледайте следните цифри:

  • Bandwidth Мярка, която определя способността на приложението да работи в върхово натоварване, независимо от паузите по време на монтажа и необходимия размер на паметта
  • GC измерване RTT, определяне на способността на приложението, за да се справят с колебания в броя на спиранията и работа GC
  • Размерът на паметта използва размерът на паметта, което е необходимо за ефективна работа на GC

Обикновено, тези характеристики са компрометирани и подобрени един от тях води до останалите разходи. За повечето приложения, и трите важни характеристики, но често един или два са по-важни за прилагане - това ще бъде отправна точка, за да се създаде.

Основни принципи на GC тунинг

Помислете три основни фундаментални разбиране на правилата за настройки GC:
  • Необходимо е да се опитаме да се гарантира, че максималният брой обекти, когато се работи пречистени малък GC (второстепенен колекция grabage). Този принцип позволява да се намали броя и честотата на пълната колекция на боклук (пълно събиране на боклука) - чиято работа е основната причина за големи закъснения в прилагането
  • Колкото повече памет се разпределя към заявлението, по-добре събирането на боклука, и толкова по-добре постигнатите количествени характеристики на трафик и време за реакция
  • Ефективно конфигурира само две от трите количествени характеристики - производителност, времето за реакция, разпределена памет размер - при ефективната стойност на необходимия размер на паметта се разбира минимизиране

ние ще извършите експеримент с:

За който се активира режимът по подразбиране - сървър и UseParallelGC (многонишковите операция фаза събиране на боклук малък)

За да изчислите общата сума на колектор пауза боклук може да работи в режим:

И обобщи забавяне клисура gc.log на:

Къде недвижими = 0.01 сек - действителното време, прекарано на сглобяване.

И можете да използвате помощната програма VisualVm, плъгин инсталиран VisualGC, което ясно може да се види разпределението на паметта в различни области на GC (Eden, Survivor1, Survivor2, старо) и да видите статистически данни за началото и продължителността на събиране на боклук.

Определяне на необходимия размер на паметта


За да започнете, трябва да стартирате приложението, с възможно най-голям обем памет, отколкото е действително необходима молба. Ако не знаехме първоначално колко ще отнеме нашата молба в паметта - можете да стартирате приложението, без да се посочва -Xmx и -Xms и HotSpot VM ще изберете размера на паметта. Ако в началото на прилагането ние ще се OutOfMemory (Java купчина пространство или PermGen пространство), тогава можем да итеративно се увеличи размерът на паметта на разположение (-Xmx или -XX: PermSize), докато грешката е изчезнала.
Следващата стъпка е да се изчисли размерът на дълготрайните живо данни - размера на старите и постоянни области на купчината след фазата на пълното събиране на боклука. Този размер - приблизителния размер на паметта, необходима за функционирането на заявлението, за да я получи, можете да видите размера на площта, след серия от цялото събрание. Обикновено размерът на паметта, необходима за прилагането -Xms и -Xmx 3-4 пъти повече от сумата, на живи данни. Така че, за да дневника, по-горе - стара стойност на терена след фаза на пълно събиране на боклука - 349363K. Тогава предложената стойност -Xmx и -Xms

1400 MB. -XX: PermSize и -XX: MaxPermSize - 1.5 пъти повече от PermGenSize След фазата на пълното събиране на боклука - 13324K

20 MB. Размерът на младото поколение отнема еднакъв размер 1-1,5 обем на живо данни

525 MB. Тогава ние се низ JVM тичам със следните параметри:

В VisualVm получаваме следната картина:

Основните принципи на настройките за събиране на боклук от нулата

Като цяло е постигнат 54 монтаж за 30 секунди от експеримента - 31 малки и 23 пълен - с общо време за спиране 3,227c. Този размер на закъснение не може да отговори на необходимите изисквания - ще видим дали можем да подобрим ситуацията, без да променя кода на приложението.

Създаване допустимото време за отговор


Следните параметри трябва да се измерват и се вземат предвид при определяне на времето за реакция:
  • Измерване на малка продължителност събиране на боклука
  • Измерване на малка честота събиране на боклука
  • Измерване на дължината на най-лошия случай, пълен с събиране на боклука
  • Измерване на честотата на най-лошия случай пълната колекция на боклук
регулиране на размера на млади и стари поколение


Времето, необходимо за ниско фаза на събиране на боклука, зависи от броя на обектите в младото поколение, по-малкия му размер - по-ниската продължителност, но се увеличава честотата, тъй като област често започва да се запълнят. Опитайте се да намалите времето на всяка малка събрание чрез намаляване на размера на младото поколение, като същевременно се запази размера на старата генерация. Грубо може да се изчисли, че всяка секунда ние трябва да се изчисти в младото поколение 50potokov 8obektov * * 1MB

400Mbps. Стартирайте със следните параметри:

В VisualVm получаваме следната картина:

Основните принципи на настройките за събиране на боклук от нулата

Общото време на боклука, ние не бяхме в състояние да засегне малък строителство - 1,533s - повишена честота на малки възли, но общото време се е влошило - 3661 се дължи на факта, че повишена честота на старата генерация и повишената честота на повикване пълна колекция боклук запълни. За да се преодолее това - се опита да увеличи размера на старото поколение - JVM план със следните параметри:

Основните принципи на настройките за събиране на боклук от нулата

Общо пауза вече е подобрена и е в размер на 2 637 с обща стойност, необходима за памет за приложения, като в същото време намалява - по този начин итеративно, можете да се намери правилният баланс между старото и младото поколение за разпределение на времето на живот на обектите в дадено приложение.

Когато времето, все още не е удовлетворен от нас - можете да отидете на колектора едновременното боклук, включително -XX на опция: + UseConcMarkSweepGC - алгоритъм, който ще се опита да извърши работа по същество относно маркировката обекти за заличаване в отделен поток тече паралелни приложения.

Създаване Едновременното събирач на боклука


ConcMarkSweep GC изисква по-внимателни настройки - една от основните цели е да се намали стоп-света спира при липса на достатъчно пространство в старата генерация на позициите на обекти - като Тази фаза отнема средно по-дълго от фазата на пълното събиране на боклука, когато пропускателна GC. В резултат на това - може да увеличи продължителността на най-лошия случай събирането на боклука, е необходимо да се избегнат честите преливания старата генерация. Като правило, - прехода към ConcMarkSweep GC препоръча увеличаване на размера на възраст поколение с 20-30% - JVM тече със следните параметри:

Основните принципи на настройките за събиране на боклук от нулата

Общо почивка спадна до 1,923 секунди.

оцелял регулиране на размера


В рамките на графиката по-долу можете да видите размера на паметта на разпределението на приложения в зависимост от броя на прехода между етапи на Eden, Survivor1 и Survivor2 преди да стигнем до Стария поколение. Факт е, че един от начините да се намали броят на залято в старата генерация ConcMarkSweep GC - предотвратяване на директното движение на обекти от младото поколение директно в старата - заобикаляйки оцелял региона.

За да се следи разпределението на обектите на сцената, можете да започнете с JVM с опция -XX: + PrintTenuringDistribution.
В gc.log можем да наблюдаваме:

Общият размер на наследствена обекти - 40900584, CMS по подразбиране използва 50% бариера попълнено области оцелял. По този начин ние се получи размера на региона

80 MB. Когато бъде стартиран, е настроен параметър JVM -XX: SurvivorRatio, която се определя от формулата:

Желаещи да напусне Eden пространство с размерите на една и съща - получаваме:


Основните принципи на настройките за събиране на боклук от нулата

Разпределението е по-добре, но общото време не се е променило много, поради спецификата на приложението, факт е, че след чести малки колекции боклук размера на оцелелите обекти е винаги по-голям от размера на разположение на зоните оцелял, така че в този случай можем да дарят правилното разпределение в полза на размер Eden пространство:


Основните принципи на настройките за събиране на боклук от нулата


В резултат на това ние бяхме в състояние да се намали общия размер на паузата с 3227 до 1481 с 30 да експериментирате малко, докато се повишава общото потребление на паметта. Много или малко - зависи от специфичните особености, по-специално, като се има предвид тенденцията за намаляване на разходите за физическа памет и на принципа на максимално използване на памет - все пак е важно да се намери баланс между различните области на GC и процесът е по-творчески отколкото научна.

Колкото повече памет се разпределя към заявлението, по-добре събирането на боклука, и толкова по-добре постигнатите количествени характеристики на трафик и време за реакция Wut? С увеличаване на паметта може да се получи значително увеличение на дисперсията (опростен - разсейване) латентност. В крайно време купчина пълен комплект (пълен GC) с S-т-т (wtop света) пауза повече, което означава увеличение на латентност, ако се стигне до пълния GC.

Някои другари започват JVM с голяма Heep и периодично просто рестартирайте цяло, без да се чака пълното GC.

От класиците. В antipattern използване Apache Касандра има прекрасна таблица, която показва какво може да доведе до увеличаване на безмозъчните -Xms / Xmx.


www.datastax.com/documentation/cassandra/1.2/cassandra/architecture/architecturePlanningAntiPatterns_c.html


Ние имаме по една задача в даден -Xmx от 12G до 16G до възел Касандра бяха ужасно бавно, с висока латентност на времето за изтичане, и загубата на вложки, на 8G всичко работеше стабилно към нормалния поток (6 възел на 500-600 МБайт / и на възел за 2x SSD в RAID1).

В някои предмет рано споменах този случай, но е имало неточности. Споменатите има поток (50 Mbit / сек), приложена към входния поток на nodah да join'a с речници в паметта и denormalization на данни от захранващия поток.

Свързани статии

Подкрепете проекта - споделете линка, благодаря!