"Szia! Úgy döntöttem, adok neked még egy kis leckét a szemétszállításról."

Mint már tudjuk, a Java gép maga figyeli, ha egy objektum szükségtelenné válik, és törli azt.

– Igen. Te és Rishi korábban meséltél róla. Nem emlékszem a részletekre.

"Rendben. Akkor nézzük át újra."

Szemétszállítás - 1

"Amint létrejön egy objektum, a JVM memóriát foglal le számára. Az objektum iránti érdeklődést a referenciaváltozók segítségével figyeli. Az objektum a  szemétgyűjtés során törölhető, vagyis az az eljárás, amellyel a memória felszabadul, ha nincsenek az objektumra hivatkozó változók. tárgy. "

– Mesélj egy kicsit a szemétgyűjtőről – mi az és hogyan működik.

"OK. A szemétgyűjtés a főszálon szokott történni. 5 percenként, vagy gyakrabban. Ha nem volt elég szabad memória, a Java gép felfüggeszti az összes szálat, és törölte a nem használt objektumokat."

"De ezt a megközelítést most elvetették. A következő generációs szemétgyűjtő a színfalak mögött és egy külön szálon dolgozik. Ezt hívják párhuzamos szemétgyűjtésnek."

"Értem. Pontosan hogyan döntenek arról, hogy törölnek egy objektumot vagy sem?"

"Az objektumra való hivatkozások számának pusztán megszámlálása nem túl hatékony – lehetnek olyan objektumok, amelyek egymásra hivatkoznak, de más objektumok nem hivatkoznak rájuk."

"Tehát a Java más megközelítést alkalmaz.  A Java az objektumokat elérhetőre és elérhetetlenre osztja.  Egy objektum elérhető (élő), ha egy másik elérhető (élő) objektum hivatkozik rá. Az elérhetőséget a szálak határozzák meg. A futó szálakat mindig elérhetőnek (élőnek) tekintik. , még ha senki sem hivatkozik rájuk."

"Rendben. Azt hiszem, értem."

"Hogyan történik a tényleges szemétgyűjtés – a szükségtelen tárgyak törlése?"

"Egyszerű. A Java-ban a memória megegyezés szerint két részre van osztva, és amikor eljön a szemétgyűjtés ideje, az összes élő (elérhető) objektumot a memória másik részébe másolják, és a régi memória mind felszabadul."

"Ez egy érdekes megközelítés. Nem kell számolni a hivatkozásokat: másolja át az összes elérhető objektumot, és minden más szemét."

"Ez egy kicsit bonyolultabb ennél. A Java programozók azt találták, hogy az objektumokat általában két kategóriába sorolják: hosszú élettartamúak (amelyek a program teljes futása alatt léteznek) és rövid élettartamúak (amelyekre a módszerekben és a «helyi) végrehajtáshoz van szükség. " tevékenységek)."

"Sokkal hatékonyabb a hosszú élettartamú tárgyakat elkülöníteni a rövid élettartamúaktól. Ehhez ki kellett találni egy módszert, amellyel meghatározható a tárgy élettartama."

"Tehát, az összes memóriát »generációkra" osztották fel. Vannak első generációs objektumok, második generációs objektumok stb. A memória minden törlésekor a generációszámláló 1-gyel nő. Ha bizonyos objektumok több generációban léteznek, akkor hosszú életűként tartják nyilván."

"Ma a szemétgyűjtő a Java nagyon összetett és hatékony része. Számos része heurisztikusan működik – olyan algoritmusokon alapul, amelyek találgatásokat tesznek. Ennek eredményeként gyakran "nem hallgat" a felhasználóra."

– Jelentése?

"A Java-nak van egy szemétgyűjtő ( GC ) objektuma, amely a System.gc () metódussal hívható meg ."

" A System.runFinalization() segítségével kikényszerítheti a törlendő objektumok véglegesítési metódusainak hívását. De tény, hogy a Java dokumentáció szerint ez nem garantálja sem a szemétgyűjtés megindulását, sem azt, hogy a finalize( ) metódus lesz meghívva.  A szemétgyűjtő dönti el, hogy mikor hívja és mire. "

"Hú! Jó tudni."

"De van még több is. Mint tudod, a Java-ban egyes objektumok másokra hivatkoznak. Ezt a hivatkozási hálózatot használják annak meghatározására, hogy egy objektumot törölni kell-e."

"És nézd. A Java speciális referenciákkal rendelkezik, amelyek segítségével befolyásolhatja ezt a folyamatot. Vannak speciális wrapper osztályok számukra. Itt vannak:"

" A SoftReference  egy puha referencia."

" A gyenge hivatkozás  gyenge hivatkozás."

" A PhantomReference egy fantomreferencia."

"Uh... Ez a belső osztályokra, a beágyazott osztályokra, a beágyazott névtelen osztályokra és a helyi osztályokra emlékeztet. A nevek különbözőek, de egyáltalán nem világos, hogy mire valók."

"Mondd, Amigo, programozó lettél. Most haragszol az osztálynevek miatt, mondván: "nem elég informatívak, és egy névvel(!) lehetetlen meghatározni, hogy ez az osztály mit csinál, hogyan, és miért"."

"Hűha. Észre sem vettem. De annyira nyilvánvaló."

"Rendben. Elég a szóból. Hadd meséljek a SoftReferences-ről."

"Ezeket a hivatkozásokat kifejezetten gyorsítótárazásra tervezték, bár más célokra is felhasználhatók – mindezt a programozó belátása szerint."

"Íme egy példa egy ilyen hivatkozásra:"

Példa
// 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();

"Ha egy tárgyra az egyetlen utalás lágy, akkor az tovább él, és "puhán elérhetőnek" nevezik."

"De!  A csak puha hivatkozásokkal hivatkozott objektumokat a szemétgyűjtő törölheti, ha a programnak nincs elég memóriája. Ha hirtelen a programnak nincs elég memóriája, az OutOfMemoryException  kivétele előtt a szemétgyűjtő törli az összes objektumot lágy hivatkozások hivatkoznak rá, és újra megpróbálja lefoglalni a memóriát a programnak."

"Tegyük fel, hogy egy kliensprogram gyakran kér különféle adatokat egy szerverprogramtól. A kiszolgálóprogram egy SoftReference segítségével gyorsítótárazhatja azokat. Ha a puha hivatkozások által a haláltól megóvott objektumok elfoglalják a memória nagy részét, akkor a szemétgyűjtő egyszerűen törli őket. minden. Gyönyörű!"

– Igen, nekem is tetszett.

"Nos, egy apró kiegészítés: A SoftReference osztálynak két metódusa van. A get() metódus a SoftReference által hivatkozott objektumot adja vissza . Ha az objektumot a szemétgyűjtő törölte, a get () metódus hirtelen nullát kezd visszaadni."

"A felhasználó explicit módon is törölheti a SoftReference-t a clear() metódus meghívásával. Ebben az esetben a SoftReference objektumon belüli gyenge láncszem megsemmisül."

"Ez minden most."

– Köszönöm az érdekes történetet, Ellie. Tényleg nagyon érdekes volt.