JavaRush /Java Blog /Random-TL /Coffee break #210. Lahat ng Uri ng Mga Mangongolekta ng B...

Coffee break #210. Lahat ng Uri ng Mga Mangongolekta ng Basura sa Java na Dapat Mong Malaman

Nai-publish sa grupo
Source: Hackernoon Sa pamamagitan ng post na ito, malalaman mo ang mga kalakasan at kahinaan ng bawat uri ng garbage collector na ginagamit sa Java development. Coffee break #210.  Lahat ng Uri ng Mga Mangongolekta ng Basura sa Java na Dapat Mong Malaman - 1Ang tanong tungkol sa Garbage Collector (GC) ay maririnig sa halos bawat panayam. Kaya nagpasya akong kolektahin ang lahat ng kinakailangang impormasyon tungkol sa kanila gamit ang aking paboritong prinsipyo - maikli at simple. Una, magsimula tayo sa layunin ng CG at kung bakit kailangan natin ng maraming uri ng mga basurero. Sa mga wikang tulad ng C, kailangan nating mag-imbak ng impormasyon ng bagay sa memorya at magsulat ng maraming boilerplate code upang palayain ang memorya na iyon. Siyempre, ang mga pagtagas ng memorya ay karaniwan sa mga naturang programa. Niresolba ng Java ang problema ng memory leaks gamit ang isang garbage collector. At ikaw, bilang isang developer, ay dapat na malaman kung aling basurero ang pinakamahusay na gamitin. Marami ang nakasalalay sa kung saan at kung paano tumatakbo ang iyong programa. Maaaring tumakbo ito sa mahinang hardware o may malaking bilang ng mga bagay, o dapat ay napakabilis ng iyong programa. Batay sa mga kundisyong ito, dapat mong ibagay ang iyong tagakolekta ng basura upang makamit ang ninanais na pagganap. Kaya, magsimula tayo.

Paano nakikitungo ang JVM sa memorya

Hinahati ng Java Virtual Machine (JVM) ang memorya sa dalawang lugar: ang heap, na nag-iimbak ng data ng application, at ang non-heap, na nag-iimbak ng program code at iba pang data. Ituon natin ang ating atensyon sa lugar ng heap. Ito ay kung saan ang aming programa ay lumilikha ng mga bagong bagay. Ang lahat ng mga kolektor ng basura ay batay sa katotohanan na maraming mga programa ang gumagamit ng mga ephemeral na bagay. Iyon ay, ang mga bagay na ito ay nilikha, pagkatapos ay natupad ang kanilang pag-andar at hindi na kailangan. Karamihan sa mga naturang bagay. Ngunit ang ilang mga bagay ay nabubuhay nang mas matagal, marahil kahit na sa buong tagal ng programa. Dito lumitaw ang ideya ng paghahati ng mga bagay sa mga bata at lumang henerasyon. At kailangan nating suriin nang madalas ang nakababatang henerasyon. Ang katotohanan ay ang mga proseso ng pagkolekta ng basura ay nahahati sa maliit na paglilinis, na nakakaapekto lamang sa nakababatang henerasyon, at kumpletong paglilinis, na maaaring makaapekto sa parehong henerasyon. Tandaan na ang tagakolekta ng basura ay isang programa. At nangangailangan ito ng oras at mga mapagkukunan mula sa iyong computer upang gumana. Na nakakaapekto rin sa aming aplikasyon. Paano ito nakakaapekto? Halimbawa, upang maisagawa ang pangongolekta ng basura, ipo-pause ng JVM ang aming aplikasyon. Ito ay tinatawag na Stop-The-World (STW) pause. Sa panahong ito, ang lahat ng mga thread ng aplikasyon ay sinuspinde. Ngunit ang application sa loob ay ganap na hindi nakakaalam nito. Para sa aplikasyon, ang oras ay dumadaloy nang pantay-pantay. Bakit ito napakasama? Isipin mo na lang, nagsusulat ka ng ilang uri ng exchange application o application para sa autopilot ng eroplano. Ang iyong aplikasyon ay maaaring matulog nang isang segundo, at ang likas na katangian ng iyong problema ay maaaring magbago nang malaki. Iyon ay, ang pag-pause ay isang makabuluhang parameter para sa bawat kolektor ng basura. Ang susunod na pangunahing pag-aari ng kolektor ng basura ay ang kabuuang oras na ginugol sa pagkolekta ng basura kaugnay sa kabuuang oras ng pagpapatupad ng programa. Ano ang ibig sabihin nito at bakit ito napakahalaga? Sa halip na isang malaking yugto ng "Stop-The-World", maaari tayong pumili ng algorithm na may maraming maliliit na pag-pause. Mas mainam ang maliliit na pahinga, ngunit wala nang libre. Sa kasong ito, nagbabayad kami sa pamamagitan ng pagtaas ng kabuuang oras ng pagpapatupad ng programa. At dapat din natin itong isaalang-alang. Ang susunod na parameter ay ang dami ng mga mapagkukunan ng hardware. Ang bawat kolektor ay nangangailangan ng memorya upang mag-imbak ng impormasyon ng bagay at isang processor upang magsagawa ng paglilinis. Ang huling parameter ay bilis. Ang kahusayan sa pangongolekta ng basura ay tumutukoy sa kung gaano kabilis at kahusay ang pag-reclaim ng garbage collector (GC) ng memorya na hindi na ginagamit ng isang programa. Ang lahat ng mga parameter na ito ay nakakaimpluwensya sa algorithm, na maaaring magbakante ng memorya nang mabilis hangga't maaari habang kumukonsumo ng kaunting mapagkukunan. Tingnan natin ang mga basurero na magagamit natin. Para sa panayam kailangan mong malaman ang unang lima. Ang dalawa pa ay mas mahirap.

Serial GC

Ang Serial GC ay ang tagakolekta ng basura ng Java Virtual Machine at ginagamit na ito mula pa noong simula ng Java. Ito ay kapaki-pakinabang para sa mga program na may maliit na tambak at tumatakbo sa hindi gaanong makapangyarihang mga makina. Hinahati ng basurero na ito ang tambak sa mga rehiyon, na kinabibilangan ng Eden at Survivor. Ang rehiyon ng Eden ay ang pool kung saan ang memorya para sa karamihan ng mga bagay ay unang inilalaan. Ang Survivor ay isang pool na naglalaman ng mga bagay na nakaligtas sa koleksyon ng basura sa rehiyon ng Eden. Habang napupuno ang heap, inililipat ang mga bagay sa pagitan ng mga rehiyon ng Eden at Survivor. Patuloy na sinusubaybayan ng JVM ang paggalaw ng mga bagay sa mga rehiyon ng Survivor at pumipili ng naaangkop na threshold para sa bilang ng mga naturang paggalaw, pagkatapos nito ay inilipat ang mga bagay sa Tenured na rehiyon. Kapag walang sapat na espasyo sa Tenured na rehiyon, ang buong koleksyon ng basura ang namamahala, na gumagawa sa mga bagay ng parehong henerasyon. Ang pangunahing bentahe ng kolektor ng basura na ito ay ang mababang mga kinakailangan sa mapagkukunan, kaya ang isang mababang-power processor ay sapat na upang maisagawa ang koleksyon. Ang pangunahing kawalan ng Serial GC ay ang mahabang pag-pause sa panahon ng pangongolekta ng basura, lalo na pagdating sa malaking halaga ng data.

Parallel CG

Ang isang parallel na kolektor ng basura (Parallel CG) ay katulad ng isang sequential constructor. Kabilang dito ang parallel processing ng ilang mga gawain at ang kakayahang awtomatikong ibagay ang mga setting ng performance. Ang Parallel GC ay isang Java Virtual Machine garbage collector batay sa mga ideya ng Serial GC, ngunit may dagdag na paralelismo at katalinuhan. Kung ang computer ay may higit sa isang core ng processor, awtomatikong pinipili ng mas lumang bersyon ng JVM ang Parallel GC. Ang heap dito ay nahahati sa parehong mga rehiyon tulad ng sa Serial GC - Eden, Survivor 0, Survivor 1 at Old Gen (Tenured). Gayunpaman, maraming mga thread ang kalahok sa koleksyon ng basura nang magkatulad, at ang kolektor ay maaaring mag-adjust sa mga kinakailangang parameter ng pagganap. Ang bawat collector thread ay may memory area na kailangang i-clear. Ang Parallel GC ay mayroon ding mga setting na naglalayong makamit ang kinakailangang kahusayan sa pagkolekta ng basura. Gumagamit ang kolektor ng mga istatistika mula sa mga nakaraang koleksyon ng basura upang ibagay ang mga setting ng pagganap para sa mga koleksyon sa hinaharap. Nagbibigay ang Parallel GC ng awtomatikong pag-tune ng mga parameter ng pagganap at mas mababang oras ng pag-pause ng build, ngunit mayroong isang maliit na disbentaha sa anyo ng ilang fragmentation ng memorya. Ito ay angkop para sa karamihan ng mga application, ngunit para sa mas kumplikadong mga programa mas mahusay na pumili ng mas advanced na mga pagpapatupad ng kolektor ng basura. Mga Pros: Mas mabilis kaysa sa Serial GC sa maraming kaso. May magandang bilis. Kahinaan: Gumagamit ng mas maraming mapagkukunan at maaaring medyo mahaba ang mga pag-pause, ngunit maaari naming isaayos ang maximum na tagal ng pag-pause ng Stop-The-World.

Kasabay na Mark Sweep

Ang Concurrent Mark Sweep (CMS) garbage collector ay naglalayon na bawasan ang maximum na haba ng pag-pause sa pamamagitan ng pagpapatakbo ng ilang gawain sa pangongolekta ng basura kasabay ng mga application thread. Ang basurero na ito ay angkop para sa pamamahala ng malaking halaga ng data sa memorya. Ang Concurrent Mark Sweep (CMS) ay isang alternatibo sa Parallel GC sa Java Virtual Machine (JVM). Ito ay inilaan para sa mga application na nangangailangan ng access sa maraming mga core ng processor at sensitibo sa Stop-The-World pause. Ang CMS ay nagsasagawa ng mga hakbang sa pangongolekta ng basura kasabay ng pangunahing programa, na nagbibigay-daan dito na tumakbo nang walang tigil. Gumagamit ito ng parehong organisasyon ng memorya gaya ng mga kolektor ng Serial at Parallel, ngunit hindi naghihintay na mapunan ang Tenured area bago patakbuhin ang lumang henerasyong purga. Sa halip, tumatakbo ito sa background at sinusubukang panatilihing compact ang Tenured region. Nagsisimula ang Concurrent Mark Sweep sa isang paunang yugto ng pagmamarka na pansamantalang humihinto sa mga pangunahing thread ng application at minamarkahan ang lahat ng mga bagay na naa-access mula sa ugat. Ang mga pangunahing thread ng application pagkatapos ay magpapatuloy at ang CMS ay magsisimulang maghanap para sa lahat ng mga aktibong bagay na naa-access ng mga link mula sa mga minarkahang root object. Matapos markahan ang lahat ng nabubuhay na bagay, nililimas ng kolektor ang memorya ng mga patay na bagay sa maraming magkatulad na mga thread. Ang isa sa mga benepisyo ng isang CMS ay ang pagtutok nito sa pagliit ng downtime, na mahalaga para sa maraming aplikasyon. Gayunpaman, nangangailangan ito ng sakripisyo sa mga tuntunin ng mga mapagkukunan ng CPU at pangkalahatang bandwidth. Bilang karagdagan, ang CMS ay hindi nag-compress ng mga bagay sa lumang henerasyon, na humahantong sa fragmentation. Ang mahabang pag-pause dahil sa mga posibleng pagkabigo ng parallel mode ay maaaring maging isang hindi kasiya-siyang sorpresa (bagaman hindi ito madalas mangyari). Kung may sapat na memorya, maiiwasan ng CMS ang mga ganitong paghinto. Pros: Mabilis. May maliliit na Stop-The-World na paghinto. Cons: kumukonsumo ng mas maraming memorya; kung walang sapat na memorya, maaaring mahaba ang ilang pag-pause. Hindi masyadong maganda kung ang application ay lumilikha ng maraming bagay.

Basura-Una

Ang Garbage-First (G1) ay itinuturing na alternatibo sa isang CMS, lalo na para sa mga application ng server na tumatakbo sa mga multi-processor server at pamamahala ng malalaking set ng data. Ang G1 garbage collector ay nagko-convert ng memory sa maramihang pantay na laki ng mga rehiyon, maliban sa malalaking rehiyon (na nilikha sa pamamagitan ng pagsasama-sama ng mga regular na rehiyon upang mapaunlakan ang malalaking bagay). Ang mga rehiyon ay hindi kailangang organisahin nang sunud-sunod at maaaring baguhin ang kanilang kaugnayan sa henerasyon. Ang mga maliliit na paglilinis ay pana-panahong ginagawa para sa nakababatang henerasyon at paglipat ng mga bagay sa mga rehiyon ng Survivor o pag-upgrade sa mga ito sa mas lumang henerasyon at paglilipat ng mga ito sa Tenured. Ang paglilinis ay isinasagawa lamang sa mga rehiyon kung saan kinakailangan upang maiwasan ang paglampas sa nais na oras. Ang kolektor mismo ang hinuhulaan at pinipili ang mga rehiyon na may pinakamalaking dami ng basura para sa paglilinis. Gumagamit ang mga full sweep ng marking loop para gumawa ng listahan ng mga live na bagay na tumatakbo kasabay ng pangunahing application. Pagkatapos ng ikot ng pagmamarka, lilipat ang G1 sa pagpapatakbo ng mga halo-halong paglilinis, na nagdaragdag ng mga rehiyon ng mas lumang henerasyon sa hanay ng mga rehiyon ng mas batang henerasyon na lilinisin. Ang G1 garbage collector ay itinuturing na mas tumpak kaysa sa CMS collector sa paghula ng mga laki ng pag-pause at mas mahusay na namamahagi ng koleksyon ng basura sa paglipas ng panahon upang maiwasan ang matagal na pag-downtime ng application, lalo na sa malalaking sukat ng heap. Hindi rin ito nakakapira-piraso ng memorya tulad ng CMS collector. Gayunpaman, ang kolektor ng G1 ay nangangailangan ng higit pang mga mapagkukunan ng CPU upang tumakbo nang kahanay sa pangunahing programa, na binabawasan ang throughput ng application. Mga Pros: Gumagana nang mas mahusay kaysa sa CMS. May mas maiikling pag-pause. Cons: Kumokonsumo ng mas maraming mapagkukunan ng CPU. Kumokonsumo din ito ng mas maraming memorya kung marami tayong malalaking bagay (higit sa 500 KB) dahil inilalagay nito ang mga bagay sa isang rehiyon (1-32 MB).

Epsilon GC

Ang Epsilon GC ay idinisenyo para sa mga sitwasyon kung saan hindi kinakailangan ang pangongolekta ng basura. Hindi ito nagsasagawa ng pangongolekta ng basura, ngunit gumagamit ng TLAB (thread-local allocation buffer) upang maglaan ng mga bagong bagay - maliit na memory buffer na hinihiling ng mga indibidwal na thread mula sa heap. Ang mga malalaking bagay na hindi akma sa buffer ay humihiling ng mga bloke ng memorya na partikular para sa kanilang sarili. Kapag naubusan ng mga mapagkukunan ang Epsilon GC, bubuo ang OutOfMemoryError at matatapos ang proseso. Kasama sa mga benepisyo ng Epsilon GC ang mas mababang mga kinakailangan sa mapagkukunan at mas mabilis na paglalaan ng memorya para sa mga application na lumikha ng lahat ng mga bagay na kailangan nila sa pagsisimula o nagpapatakbo ng mga panandaliang application na hindi gumagamit ng lahat ng inilalaan na memorya. Makakatulong din ang Epsilon GC na suriin ang mga kinakailangan sa mapagkukunan na idinaragdag ng ibang mga basurero sa iyong aplikasyon. Mga Pros: Napakabilis. Cons: Hindi nag-clear ng mga bagay :) Ang susunod na dalawang collector ay ang pinaka-advanced sa kanilang uri, ngunit din ang pinaka-kumplikado. Samakatuwid, isasaalang-alang natin ang mga ito nang maikli.

ZGC

Maaaring mapanatili ng ZGC ang sub-millisecond latency kahit na nakikipag-ugnayan sa malaking halaga ng data. Ang ZGC ay isang garbage collector na binuo ng Oracle para sa Java na idinisenyo upang magbigay ng mataas na throughput at mababang latency kapag nagpoproseso ng malalaking tambak (hanggang 16 TB). Ang ZGC ay batay sa mga virtual na prinsipyo ng memorya at gumagamit ng iba't ibang kulay na mga marka upang subaybayan ang estado ng mga bagay sa panahon ng pagkolekta ng basura. Mga kalamangan: Ang mga pag-pause ay mas mababa sa isang millisecond, kahit na sa malalaking tambak, na lubhang kapaki-pakinabang para sa mga application na nangangailangan ng maikling oras ng pagproseso ng query. Gumagana ito sa napakalaking tambak na may mahusay na throughput. Maaaring i-compress ng ZGC ang heap memory sa panahon ng pagkolekta ng basura. Cons: Mataas na paggamit ng CPU at makabuluhang mga kinakailangan sa pagganap, na maaaring makapagpabagal sa mga oras ng paglulunsad ng application.

Shenandoah G.C.

Ang Shenandoah GC ay isa pang kolektor ng basura na may maikling paghinto anuman ang laki ng tambak. Ang kolektor ng basura na ito ay binuo ng Red Hat. Ito ay idinisenyo upang mabawasan ang oras na ginugugol ng isang aplikasyon sa pagkolekta ng basura. Tulad ng ZGC, isa itong parallel collector, na nangangahulugang tumatakbo ito habang tumatakbo ang application, na pinapaliit ang mga pag-pause. Gumagamit ang Shenandoah GC ng “forwarding pointers” para ilipat ang mga bagay sa panahon ng pangongolekta ng basura. Mayroon din itong pamamaraan na tinatawag na "load barrier removal" upang mapabuti ang pagganap. Mga Kalamangan: Maaaring makamit ng Shenandoah GC ang mga maikling oras ng pag-pause, kadalasang mas mababa sa 10ms, kahit na para sa napakalaking tambak. Magandang throughput. Cons: mataas na processor load at kahirapan sa pagtatrabaho sa ilalim ng mabibigat na load.

Konklusyon

Ang mga kolektor ng basura ay isa sa pinakamahirap na gawain sa programming. Ang mga bagong pag-unlad ay patuloy na isinasagawa sa direksyon na ito. Bagama't bihira para sa mga programmer na i-tweak ang GC, kailangan mo pa ring magkaroon ng kahit man lang lumilipas na kaalaman sa kung paano gumagana ang iyong tool sa pangongolekta ng basura.
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION