Zeven types van JAVA-afvalverzamelaars
In dit document wordt uitgelegd wat de afvalverzamelaar in java is en wat de belangrijkste types afvalverzamelaars zijn met het gedrag van elke afvalverzamelaar. In dit artikel leg ik niet uit hoe heap-allocatie gebeurt en hoe major/minor garbage collectors starten. Het zal uitleggen in het volgende artikel. Java is een object-georiënteerde programmeertaal die Automatische Garbage Collection bevat. Java wijst automatisch geheugen toe en wijst het toe, zodat programma’s niet met die taak worden belast. Nu (Java-12), Java heeft zeven soorten garbage collectors, De 5e en 6e garbage collectors zijn in java 11 geïntroduceerd en de 7e is in java 12 geïntroduceerd. In de meeste toepassingen in de productie heeft gebruik gemaakt van de eerste vier soorten garbage collectors. Sinds de laatste drie garbage collectors recent in beeld zijn gekomen. Ja, inderdaad. We moeten ons zorgen maken over de GC en zijn gedrag. Omdat het een significant verschil in prestatie kan opleveren. Elke GC heeft zijn eigen voor- en nadelen. Als ontwikkelaars moeten we een duidelijk idee hebben van het gedrag van alle garbage collectors en moeten we een garbage collector kiezen op basis van ons bedrijfsscenario. Wij kunnen een garbage collector kiezen door, de keuze als een JVM argument door te geven. Dit is de eenvoudigste GC implementatie. Het is in principe ontworpen voor een single thread omgeving. Deze GC implementatie bevriest alle applicatie threads wanneer het loopt. Het gebruikt enkele draad voor vuilnisophaling. Daarom is het geen goed idee om het in multi-threaded toepassingen zoals serveromgevingen te gebruiken. Om de seriële vuilnisman in te schakelen, kunnen we het volgende argument gebruiken: java -XX:+UseSerialGC -jar Application.java De parallelle vuilnisman wordt ook wel een doorvoer-verzamelaar genoemd. In tegenstelling tot de seriële garbage collector, gebruikt deze meerdere threads voor garbage collection. Net als de seriële garbage collector bevriest deze ook alle applicatie-threads tijdens het uitvoeren van garbage collection. De vuilnisman is het meest geschikt voor toepassingen die toepassingspauzes kunnen verdragen. Om de parallelle vuilnisman in te schakelen, kunnen we het volgende argument gebruiken: java -XX:+UseParallelGC -jar Application.java Als we deze GC gebruiken, kunnen we maximale garbage collection-threads en pauzetijd, doorvoer en voetafdruk (heapgrootte) Het aantal garbage collector-threads kan worden geregeld met de opdrachtregeloptie -XX:ParallelGCThreads=<N> Het doel voor de maximale pauzetijd (het gat tussen twee GC) kan worden opgegeven met de opdrachtregeloptie -XX:MaxGCPauseMillis=<N> Het maximale doorvoerdoel (gemeten aan de hand van de tijd die wordt besteed aan garbage collection versus de tijd die buiten garbage collection wordt doorgebracht) wordt opgegeven met de commandoregeloptie -XX:GCTimeRatio=<N> Een maximale heap footprint (de hoeveelheid heap-geheugen die een programma nodig heeft tijdens het uitvoeren) wordt opgegeven met de optie -Xmx<N>. Concurrent Mark Sweep (CMS) afvalverzamelaar gebruikt meerdere garbage collector threads voor afvalverzameling. Het scant het heap geheugen om instanties te markeren voor evictie en veegt dan de gemarkeerde instanties. Het is ontworpen voor toepassingen die de voorkeur geven aan kortere vuilnisophaalpauzes, en die het zich kunnen veroorloven om processorbronnen te delen met de vuilnisman terwijl de toepassing draait. CMS-afvalverzamelaar houdt alle toepassingsthreads alleen in de volgende twee scenario’s In vergelijking met de parallelle garbage collector, gebruikt CMS collector meer CPU om een betere applicatie doorvoer te garanderen. Als we meer CPU kunnen toewijzen voor betere prestaties, dan verdient de CMS-afvalverzamelaar de voorkeur boven de parallelle verzamelaar. Om de CMS-afvalverzamelaar in te schakelen, kunnen we het volgende argument gebruiken: java -XX:+USeParNewGC -jar Application.java G1 (Garbage First) Garbage Collector is ontworpen voor toepassingen die op multiprocessormachines met veel geheugenruimte worden uitgevoerd. Het is beschikbaar sinds JDK7 Update 4 en in latere releases. Het verdeelt het heap-geheugen in regio’s en verzamelt daarbinnen parallel. G1 comprimeert ook de vrije heap ruimte onderweg, net na het terugwinnen van het geheugen. Maar CMS vuilnisman comprimeert het geheugen op stop de wereld (STW) situaties. G1 verzamelaar zal de CMS verzamelaar vervangen omdat het meer prestatie efficiënt is. In G1 verzamelaar bevat twee fasen; In tegenstelling tot andere verzamelaars, G1 verzamelaar verdeelt de heap in een set van gelijke grootte heap regio’s, elk een aaneengesloten bereik van virtueel geheugen. Bij het uitvoeren van afvalverzamelingen, toont G1 een gelijktijdige globale markeringsfase om de levendigheid van objecten in de hele heap te bepalen. Nadat de markeringsfase is voltooid, weet G1 welke regio’s het meest leeg zijn. Het verzamelt eerst in deze gebieden, wat meestal een aanzienlijke hoeveelheid vrije ruimte oplevert. Daarom wordt deze methode van vuilnisverzameling Garbage-First genoemd. Om G1 vuilnisverzamelaar in te schakelen, kunnen we het volgende argument gebruiken: java -XX:+UseG1GC -jar Application.java Epsilon is een niet-operationele of een passieve vuilnisverzamelaar. Het wijst het geheugen voor de toepassing toe, maar verzamelt niet de ongebruikte objecten. Wanneer de toepassing de Java heap uitput, sluit de JVM af. Dit betekent dat de Epsilon vuilnisman applicaties zonder geheugen laat zitten en laat crashen. Het doel van deze vuilnisman is het meten en beheren van de prestaties van applicaties. Actieve vuilnismannen zijn complexe programma’s die in de JVM naast uw applicatie draaien. Epsilon verwijdert de impact die GC heeft op de prestaties. Er zijn geen GC cycles of lees of schrijf barrières. Wanneer de Epsilon GC gebruikt wordt, draait de code in isolatie. Epsilon helpt om te visualiseren hoe garbage collection de prestaties van de app beïnvloedt en wat de geheugen drempel is aangezien het zal tonen wanneer het opraakt. Als we bijvoorbeeld denken dat we maar één gigabyte geheugen nodig hebben voor onze applicatie, kunnen we het draaien met -Xmx1g en het gedrag zien. Als die geheugentoewijzing niet voldoende is, voer het dan opnieuw uit met een heap dump. Merk op dat we deze optie moeten aanzetten om een heap dump te krijgen. We kunnen dit argument gebruiken om een heap dump te krijgen als de applicatie crasht door een tekort aan geheugen. XX:HeapDumpOnOutOfMemoryError Als we elk beetje prestatie uit onze applicatie willen halen, is Epsilon misschien wel de beste optie voor een GC. Maar we moeten een volledig begrip hebben van hoe onze code geheugen gebruikt. Als het bijna geen vuilnis creëert of als u precies weet hoeveel geheugen het gebruikt voor de periode waarin het draait, is Epsilon een uitvoerbare optie. Om Epsilon Garbage Collector in te schakelen, kunnen we het volgende argument gebruiken: java -XX:+UseEpsilonGC -jar Application.java ZGC voert al het dure werk gelijktijdig uit, zonder de uitvoering van toepassingsthreads langer dan 10 ms te stoppen, waardoor het geschikt is voor toepassingen die een lage latency vereisen en/of een zeer grote heap gebruiken. Volgens de Oracle documentatie kan het multi-terabyte heaps aan. Oracle introduceerde ZGC in Java 11. De Z garbage collector voert zijn cycli uit in zijn threads. Hij pauzeert de applicatie gemiddeld 1 ms. De G1- en Parallel-verzamelaars hebben een gemiddelde van ongeveer 200 ms. In Java 12 voegde Oracle prestatieverbeteringen en class unloading toe, hoewel Z nog steeds een experimentele status heeft. Het is alleen beschikbaar op 64-bit Linux. Maar ZGC maakt gebruik van 64-bit pointers met een techniek genaamd pointer coloring. Gekleurde pointers slaan extra informatie op over objecten op de heap. Dit is een van de redenen waarom het beperkt is tot de 64-bit JVM. In dit artikel is dit scenario diepgaand uitgelegd (https://www.opsian.com/blog/javas-new-zgc-is-very-exciting/). ZGC doet zijn markering in drie fasen. 1. Korte stop-de-wereld fase – Het onderzoekt de GC wortels, lokale variabelen die naar de rest van de heap wijzen. Het totale aantal van deze wortels is meestal minimaal en schaalt niet met de grootte van de belasting, dus ZGC’s pauzes zijn erg kort en nemen niet toe als je heap groeit. 2. Concurrent fase – Het loopt de object grafiek en onderzoekt de gekleurde pointers, het markeren van toegankelijke objecten. De belastingbarrière voorkomt onenigheid tussen de GC-fase en de activiteit van een applicatie. 3. Verplaatsingsfase – Het verplaatst levende objecten om grote secties van de heap vrij te maken om toewijzingen sneller te maken. Wanneer de verplaatsingsfase begint, verdeelt ZGC de heap in pagina’s en werkt aan één pagina per keer. Zodra ZGC klaar is met het verplaatsen van wortels, gebeurt de rest van de verhuizing in een gelijktijdige fase. ZGC zal proberen om het aantal threads zelf in te stellen, en meestal is dat juist. Maar als ZGC te veel threads heeft, zal het je applicatie uithongeren. Als het er niet genoeg heeft, zal je sneller vuilnis maken dan de GC het kan verzamelen. De fasen van ZGC laten zien hoe het grote heaps beheert zonder de prestaties te beïnvloeden als het applicatiegeheugen groeit. Om Z Garbage Collector in te schakelen, kunnen we het volgende argument gebruiken: java -XX:+UseZGC -jar Application.java Shenandoah is een vuilnisverzamelaar met een ultralage pauzetijd die de pauzetijden van GC verkort door meer vuilnisverzamelwerk gelijktijdig uit te voeren met het draaiende Java-programma. CMS en G1 doen beide gelijktijdige markering van levende objecten. Shenandoah voegt gelijktijdige compactie toe. Shenandoah gebruikt geheugenregio’s om te beheren welke objecten niet langer in gebruik zijn en welke levend zijn en klaar voor compressie. Shenandoah voegt ook een forwarding pointer toe aan elk heap object en gebruikt deze om de toegang tot het object te controleren. Het ontwerp van Shenandoah verruilt gelijktijdige CPU cycli en ruimte voor verbeteringen in de pauzetijd. De forwarding pointer maakt het makkelijk om objecten te verplaatsen, maar de agressieve bewegingen betekenen dat Shenandoah meer geheugen gebruikt en meer parallel werk vereist dan andere GC’s. Maar het doet het extra werk met zeer korte stop-de-wereld pauzes. Shenandoah verwerkt de heap in vele kleine fasen, waarvan de meeste gelijktijdig met de applicatie. Dit ontwerp maakt het mogelijk voor de GC om een grote heap efficiënt te beheren. We kunnen Shenandoah configureren met een van de drie heuristieken. Zij bepalen wanneer de GC zijn cycli start en hoe het regio’s selecteert voor evacuatie. 1. Adaptief: Observeert GC-cycli en start de volgende cyclus zodat deze is voltooid voordat de applicatie de heap heeft opgebruikt. Deze heuristiek is de standaard mode. 2. Statisch: Start een GC-cyclus op basis van heapbezetting en allocatiedruk. 3. Compact: Voert GC-cycli continu uit. Shenandoah start een nieuwe cyclus zodra de vorige is afgelopen of gebaseerd op de hoeveelheid heap-allocatie sinds de laatste cyclus. Deze heuristiek veroorzaakt doorvoer overhead maar biedt de beste ruimte terugwinning. Shenandoah moet heap sneller verzamelen dan de applicatie die het bedient deze toewijst. Als de toewijzingsdruk te hoog is en er niet genoeg ruimte is voor nieuwe toewijzingen, zal er een storing optreden. Shenandoah heeft configureerbare mechanismen voor deze situatie. Shenandoah biedt dezelfde voordelen als ZGC met grote heaps maar meer afstemmingsopties. Afhankelijk van de aard van uw toepassing, kunnen de verschillende heuristieken een goede match zijn. De pauzetijden zijn misschien niet zo kort als die van ZGC, maar ze zijn voorspelbaarder. Om de Shenandoah Garbage Collector in te schakelen, kunnen we het volgende argument gebruiken: java -XX:+UseShenanodoahC -jar Application.java Het doel van dit artikel is om een overzicht te geven van alle garbage collectors. Daarom zijn enkele inhoudelijke delen uit de gegeven referenties gehaald. We moeten een duidelijk idee hebben van de garbage collectors om een optimale garbage collector te selecteren voor onze applicatie gebruikssituaties. De optimale vuilnisman zal de prestaties van onze toepassing aanzienlijk verbeteren.
Moeten we ons zorgen maken over GC’s?
Serial Garbage Collector
Parallelle vuilnisman
CMS-afvalverzamelaar
G1 Garbage Collector
Epsilon vuilnisverzamelaar
Z garbage collector
Shenandoah
Conclusie
Reference