"Hallo! Ik heb besloten om je nog een kleine les te geven over afvalinzameling."

Zoals u al weet, controleert de Java-machine zelf wanneer een object overbodig wordt en verwijdert het.

'Ja. Jij en Rishi hebben me er eerder over verteld. Ik herinner me de details niet meer.'

"Oké. Laten we het dan nog eens doornemen."

Afvalinzameling - 1

"Zodra een object is gemaakt, wijst de JVM er geheugen voor toe. Interesse in het object wordt gecontroleerd met behulp van referentievariabelen.  Een object kan worden verwijderd tijdens het opschonen, dat wil zeggen de procedure waarmee geheugen wordt vrijgegeven als er geen variabelen zijn die verwijzen naar het object. bezwaar maken. "

'Vertel me eens iets over de vuilnisophaler - wat het is en hoe het werkt.'

"Ok. Garbage collection gebeurde vroeger op de hoofdthread. Elke 5 minuten, of vaker. Als er ooit niet genoeg vrij geheugen was, stopte de Java-machine alle threads en verwijderde ongebruikte objecten."

"Maar deze aanpak is nu verlaten. De next-gen vuilnisman werkt achter de schermen en op een aparte thread. Dit wordt gelijktijdige afvalinzameling genoemd."

"Ik begrijp het. Hoe wordt precies de beslissing genomen om een ​​object wel of niet te verwijderen?"

"Alleen al het aantal verwijzingen naar een object tellen is niet erg effectief - er kunnen objecten zijn die naar elkaar verwijzen, maar er wordt niet naar verwezen door andere objecten."

"Dus Java heeft een andere benadering.  Java verdeelt objecten in bereikbaar en onbereikbaar.  Een object is bereikbaar (levend) als ernaar wordt verwezen door een ander bereikbaar (levend) object. Bereikbaarheid wordt bepaald op basis van threads. Lopende threads worden altijd als bereikbaar (levend) beschouwd. , zelfs als niemand ernaar verwijst."

"Oké. Ik denk dat ik het snap."

"Hoe gebeurt de eigenlijke afvalinzameling - het verwijderen van onnodige objecten?"

"Het is eenvoudig. In Java wordt het geheugen volgens afspraak in twee delen verdeeld, en wanneer het tijd is voor afvalinzameling, worden alle levende (bereikbare) objecten gekopieerd naar een ander deel van het geheugen en wordt het oude geheugen vrijgegeven."

"Dat is een interessante benadering. Het is niet nodig om referenties te tellen: kopieer alle bereikbare objecten en al het andere is rotzooi."

"Het is een beetje ingewikkelder dan dat. Java-programmeurs ontdekten dat objecten meestal in twee categorieën worden verdeeld: objecten met een lange levensduur (die bestaan ​​zolang het programma draait) en objecten met een korte levensduur (die nodig zijn in methoden en voor het uitvoeren van lokale " activiteiten)."

"Het is veel efficiënter om objecten met een lange levensduur gescheiden te houden van objecten met een korte levensduur. Om dit te doen, was het nodig om een ​​manier te bedenken om de levensduur van het object te bepalen."

"Dus verdeelden ze al het geheugen in "generaties". Er zijn objecten van de eerste generatie, objecten van de tweede generatie, enz. Elke keer dat het geheugen wordt gewist, wordt de generatieteller met 1 verhoogd. Als bepaalde objecten in meerdere generaties bestaan, dan worden geregistreerd als langlevend."

"Tegenwoordig is de vuilnisman een zeer complex en efficiënt onderdeel van Java. Veel van zijn onderdelen werken heuristisch - gebaseerd op algoritmen die gissingen doen. Het resultaat is dat het vaak 'niet naar' de gebruiker luistert."

"Betekenis?"

"Java heeft een GC- object (garbage collector ) dat kan worden aangeroepen met de methode System.gc ()."

"U kunt ook System.runFinalization() gebruiken om oproepen naar de afrondingsmethoden van de te verwijderen objecten te forceren. Maar het feit is dat, volgens de Java-documentatie, dit niet garandeert dat de afvalinzameling zal starten, noch dat de afronding( ) methode wordt aangeroepen.  De vuilnisophaler beslist wanneer hij wordt aangeroepen en waarop. "

"Ho! Goed om te weten."

"Maar er is meer. Zoals u weet, verwijzen sommige objecten in Java naar andere. Dit netwerk van referenties wordt gebruikt om te bepalen of een object moet worden verwijderd."

"En kijk. Java heeft speciale referenties waarmee je dit proces kunt beïnvloeden. Er zijn speciale wrapper-klassen voor. Hier zijn ze:"

" SoftReference  is een zachte referentie."

" WeakReference  is een zwakke referentie."

" PhantomReference is een fantoomreferentie."

"Uh... Dit doet me denken aan innerlijke klassen, geneste klassen, geneste anonieme klassen en lokale klassen. De namen zijn verschillend, maar het is helemaal niet duidelijk waar ze voor zijn."

"Zeg, Amigo, je bent een programmeur geworden. Nu ben je boos vanwege de klassennamen, zeggend dat ze niet informatief genoeg zijn, en dat het onmogelijk is om met één naam(!) te bepalen wat deze klas doet, hoe, en waarom"."

"Wow. Ik merkte het niet eens. Maar het is zo duidelijk."

"OK. Genoeg woorden. Laat me je vertellen over SoftReferences."

"Deze referenties zijn specifiek ontworpen voor caching, hoewel ze voor andere doeleinden kunnen worden gebruikt - alles ter beoordeling van de programmeur."

"Hier is een voorbeeld van zo'n verwijzing:"

Voorbeeld
// Create a Cat object
Cat cat = new Cat();

// Create a soft reference to a Cat object
SoftReference<Cat> catRef = new SoftReference<Cat>(cat);

// Now only the catRef soft reference points at the object
cat = null;

// Now the ordinary cat variable also references the object
cat = catRef.get();

// Clear the soft reference
catRef.clear();

"Als de enige verwijzingen naar een object zacht zijn, dan blijft het leven en wordt het 'zacht bereikbaar' genoemd."

"Maar!  Een object waarnaar alleen door zachte verwijzingen wordt verwezen, kan door de vuilnisman worden verwijderd als het programma niet genoeg geheugen heeft.  Als het programma plotseling niet genoeg geheugen heeft, voordat een OutOfMemoryException wordt gegenereerd , zal de vuilnisman alle objecten verwijderen verwezen door zachte verwijzingen en zal opnieuw proberen geheugen toe te wijzen aan het programma."

"Stel dat een clientprogramma regelmatig verschillende gegevens van een serverprogramma opvraagt. Het serverprogramma kan een SoftReference gebruiken om een ​​deel ervan in de cache op te slaan. Als objecten die door zachte referenties voor dood worden gehouden een groot deel van het geheugen in beslag nemen, verwijdert de vuilnisophaler ze gewoon. alles. Het is prachtig!"

'Ja. Ik vond het zelf ook leuk.'

"Nou, een kleine toevoeging: de klasse SoftReference heeft twee methoden. De methode get() retourneert het object waarnaar wordt verwezen door de SoftReference . Als het object is verwijderd door de vuilnisman, zal de methode get () plotseling beginnen met het retourneren van null."

"De gebruiker kan de SoftReference ook expliciet wissen door de methode clear() aan te roepen. In dit geval wordt de zwakke schakel in het SoftReference -object vernietigd."

"Dat is het voor nu."

"Bedankt voor het interessante verhaal, Ellie. Het was echt heel interessant."