"Hei! Jeg bestemte meg for å gi deg en liten leksjon om søppelinnsamling."

Som du allerede vet, overvåker Java-maskinen selv når et objekt blir unødvendig, og sletter det.

"Jepp. Du og Rishi fortalte meg om det tidligere. Jeg husker ikke detaljene."

"OK. Så la oss gå over det igjen."

Søppelhenting - 1

"Så snart et objekt er opprettet, allokerer JVM minne for det. Interessen for objektet overvåkes ved hjelp av referansevariabler.  Et objekt kan slettes under søppelinnsamling, dvs. prosedyren som minne frigjøres hvis det ikke er noen variabler som refererer til objekt. "

"Fortell meg litt om søppelsamleren - hva det er og hvordan det fungerer."

"OK. Søppelinnsamling pleide å skje på hovedtråden. Hvert 5. minutt, eller oftere. Hvis det noen gang ikke var nok ledig minne, ville Java-maskinen suspendere alle tråder og slette ubrukte objekter."

"Men denne tilnærmingen har blitt forlatt nå. Den neste generasjons søppelsamleren jobber bak kulissene og på en egen tråd. Dette kalles samtidig søppelinnsamling."

"Jeg skjønner. Hvordan er beslutningen om å slette et objekt eller ikke tatt?"

"Bare å telle antall referanser til et objekt er ikke veldig effektivt - det kan være objekter som refererer til hverandre, men som ikke refereres av andre objekter."

"Så Java tar en annen tilnærming.  Java deler objekter inn i tilgjengelige og uoppnåelige.  Et objekt er tilgjengelig (levende) hvis det refereres til av et annet tilgjengelig (levende) objekt. Tilgjengelighet bestemmes ut fra tråder. Løpende tråder anses alltid som tilgjengelige (levende) , selv om ingen refererer til dem."

"OK. Jeg tror jeg skjønner det."

"Hvordan skjer selve søppelinnsamlingen - sletting av unødvendige gjenstander?"

"Det er enkelt. I Java er minnet delt i to deler etter konvensjon, og når det er tid for søppelinnsamling, kopieres alle levende (tilgjengelige) objekter til en annen del av minnet, og det gamle minnet frigjøres."

"Det er en interessant tilnærming. Ingen grunn til å telle referanser: kopier alle tilgjengelige objekter, og alt annet er søppel."

"Det er litt mer komplisert enn som så. Java-programmerere fant ut at objekter vanligvis er delt inn i to kategorier: langlivede (som eksisterer hele tiden programmet kjører) og kortvarige (som trengs i metoder og for å utføre «lokale) » operasjoner)."

"Det er mye mer effektivt å holde gjenstander med lang levetid adskilt fra gjenstander med kort levetid. For å gjøre dette var det nødvendig å finne en måte å bestemme gjenstandens levetid."

"Så, de delte alt minne inn i «generasjoner». Det er førstegenerasjonsobjekter, andregenerasjonsobjekter osv. Hver gang minnet tømmes, økes generasjonstelleren med 1. Hvis visse objekter eksisterer i flere generasjoner, så de er registrert som langvarig."

"I dag er søppelsamleren en veldig kompleks og effektiv del av Java. Mange av delene fungerer heuristisk – basert på algoritmer som gjør gjetninger. Som et resultat av dette «lytter den ofte ikke til» brukeren."

"Betydning?"

"Java har et søppeloppsamlerobjekt ( GC ) som kan kalles ved hjelp av System.gc ()-metoden."

"Du kan også bruke System.runFinalization() for å tvinge oppkall til finaliseringsmetodene for objektene som skal slettes. Men faktum er at, ifølge Java-dokumentasjonen, garanterer denne verken at søppelinnsamlingen vil starte, eller at fullføringen( )-metoden kalles.  Søppelsamleren bestemmer når den skal kalles og på hva .

"Wow! Godt å vite."

"Men det er mer. Som du vet, i Java refererer noen objekter til andre. Dette nettverket av referanser brukes til å bestemme om et objekt skal slettes."

"Og se. Java har spesielle referanser som lar deg påvirke denne prosessen. Det finnes spesielle innpakningsklasser for dem. Her er de:"

" SoftReference  er en myk referanse."

" WeakReference  er en svak referanse."

" PhantomReference er en fantomreferanse."

"Øh... Dette minner meg om indre klasser, nestede klasser, nestede anonyme klasser og lokale klasser. Navnene er forskjellige, men det er ikke helt klart hva de er for."

"Si, Amigo, du har blitt programmerer. Nå er du sint på grunn av klassenavnene, og sier «de er ikke informative nok, og det er umulig med ett navn(!) å finne ut hva denne klassen gjør, hvordan, og hvorfor"."

"Wow. Jeg la ikke engang merke til det. Men det er så tydelig."

"OK. Nok ord. La meg fortelle deg om SoftReferences."

"Disse referansene ble spesielt designet for caching, selv om de kan brukes til andre formål - alt etter programmererens skjønn."

"Her er et eksempel på en slik referanse:"

Eksempel
// 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();

"Hvis de eneste referansene til et objekt er myke, fortsetter det å leve og kalles "mykt tilgjengelig".

"Men!  Et objekt referert kun av myke referanser kan slettes av søppelsamleren hvis programmet ikke har nok minne.  Hvis programmet plutselig ikke har nok minne, før du kaster en OutOfMemoryException , vil søppelsamleren slette alle objekter referert av myke referanser og vil prøve igjen å allokere minne til programmet."

"Anta at et klientprogram ofte ber om forskjellige data fra et serverprogram. Serverprogrammet kan bruke en SoftReference for å cache noe av det. Hvis objekter som holdes fra døden av myke referanser tar opp en stor del av minnet, sletter søppelsamleren dem ganske enkelt alt sammen. Det er vakkert!"

"Ja. Jeg likte det selv."

"Vel, ett lite tillegg: SoftReference- klassen har to metoder. Get()-metoden returnerer objektet som refereres til av SoftReference . Hvis objektet ble slettet av søppelsamleren, vil get ()-metoden plutselig begynne å returnere null."

"Brukeren kan også fjerne SoftReference eksplisitt ved å kalle clear()-metoden. I dette tilfellet vil den svake lenken inne i SoftReference- objektet bli ødelagt."

"Det er alt for nå."

"Takk for den interessante historien, Ellie. Den var virkelig veldig interessant."