8.1 Gyenge hivatkozások Java-ban
A Java-ban többféle hivatkozás létezik.
Van StrongReference – ezek a leggyakoribb hivatkozások, amelyeket minden nap létrehozunk.
Object object = new Object();//created an object
object = null;//can now be garbage collected
És három „speciális” típusú hivatkozás létezik - SoftReference, WeakReference, PhantomReference. Valójában csak egyetlen különbség van az összes hivatkozástípus között: a GC viselkedése azokkal az objektumokkal, amelyekre hivatkoznak. Az egyes linktípusok sajátosságairól a későbbiekben részletesebben is kitérünk, de egyelőre a következő ismeretek elegendőek:
- A SoftReference egy lágy referencia, ha a GC azt látja, hogy egy objektum csak puha hivatkozások láncán keresztül érhető el, akkor eltávolítja a memóriából. Talán.
- WeakReference - gyenge hivatkozás, ha a GC azt látja, hogy egy objektum csak gyenge hivatkozások láncán keresztül érhető el, akkor eltávolítja a memóriából.
- A PhantomReference egy fantomhivatkozás, ha a GC azt látja, hogy egy objektum csak fantomhivatkozási láncon keresztül érhető el, akkor eltávolítja a memóriából. Többszöri GC után.
Azt is mondhatjuk, hogy a linktípusok bizonyos fokú lágysággal rendelkeznek:
- A szokásos kemény hivatkozás bármely referencia típusú változó. A szemétgyűjtő nem takarította ki, mielőtt használaton kívül lenne.
- SoftReference . Az objektum nem használja fel az összes memóriát – garantáltan törlődik, mielőtt OutOfMemoryError fellépne. Talán korábban, a szemétgyűjtő megvalósításától függően.
- Gyenge hivatkozás . Gyengébb puha. Nem akadályozza meg a tárgy ártalmatlanítását, a szemétszállító figyelmen kívül hagyja az ilyen hivatkozásokat.
- PhantomReference . Egy objektum "elhalálozási" feldolgozására használják: az objektum a véglegesítés után elérhető a szemét összegyűjtéséig.
Ha még nem világos, mi a különbség, akkor ne aggódjon, hamarosan minden a helyére kerül. A részletek a részletekben vannak, és a részletek ezután következnek.
8.2 WeakReference és SoftReference Java nyelven
Először is nézzük meg a különbséget a WeakReference és a SoftReference között Java-ban.
Röviden, a szemétgyűjtő felszabadítja egy objektum memóriáját, ha csak gyenge hivatkozások mutatnak rá. Ha az objektumra a SoftReferences mutat, akkor a memória felszabadításra kerül, amikor a JVM-nek nagy szüksége van a memóriára.
Ez bizonyos esetekben határozott előnyt biztosít a SoftReference- nek a Strong referenciával szemben. Például a SoftReference egy alkalmazás-gyorsítótár megvalósítására szolgál, így a JVM először törli azokat az objektumokat, amelyekre csak a SoftReferences mutat.
A WeakReference kiválóan alkalmas metaadatok tárolására, például egy ClassLoaderre való hivatkozás tárolására. Ha nincs betöltve osztály, akkor ne hivatkozzon a ClassLoaderre. Ez az oka annak, hogy a WeakReference lehetővé teszi, hogy a szemétgyűjtő elvégezze a munkáját a ClassLoader-en, amint az utolsó erős hivatkozás eltávolításra került.
WeakReference példa Java nyelven:
// some object
Student student = new Student();
// weak reference to it
WeakReference weakStudent = new WeakReference(student);
// now the Student object can be garbage collected
student = null;
SoftReference példa Java nyelven:
// some object
Student student = new Student();
// weak reference to it
SoftReference softStudent = new SoftReference(student)
// now the Student object can be garbage collected
// but this will only happen if the JVM has a strong need for memory
student = null;
8.3 PhantomReference Java nyelven
A PhantomReference példány ugyanúgy jön létre, mint a WeakReference és SoftReference példákban, de ritkán használják.
A PhantomReference lehet szemétgyűjtés, ha az objektum nem rendelkezik erős (Strong), gyenge (WeakReference) vagy lágy (SoftReference) hivatkozásokkal.
Phantom referencia objektumot a következőképpen hozhat létre:
PhantomReference myObjectRef = new PhantomReference(MyObject);
A PhantomReference olyan helyzetekben használható, amikor a finalize()-nek nincs értelme. Ez a referenciatípus különbözik a többi típustól, mivel nem objektumok elérésére tervezték. Ez azt jelzi, hogy az objektumot már véglegesítették, és a szemétgyűjtő készen áll a memóriájának visszanyerésére.
Ehhez a szemétgyűjtő egy speciális ReferenceQueue- be helyezi további feldolgozás céljából. A ReferenceQueue az a hely, ahol az objektumhivatkozások memória felszabadítása céljából kerülnek elhelyezésre.
A fantomhivatkozások biztonságos módja annak, hogy megtudjuk, hogy egy objektumot eltávolítottak a memóriából. Vegyünk például egy olyan alkalmazást, amely nagyméretű képekkel foglalkozik. Tegyük fel, hogy egy képet szeretnénk betölteni a memóriába, amikor már a memóriában van, ami készen áll a szemétgyűjtésre. Ebben az esetben meg akarjuk várni, hogy a szemétgyűjtő megölje a régi képet, mielőtt betölti az új képet a memóriába.
Itt a PhantomReference rugalmas és biztonságos választás. A régi képobjektum megsemmisítése után a régi képre való hivatkozás átkerül a ReferenceQueue-ba. Ha megvan ez a link, betölthetjük az új képet a memóriába.