A Java nyelvben a memóriakezelés az objektumok lefoglalásának és lefoglalásának folyamata, amelyet memóriakezelésnek neveznek. A Java automatikusan végzi a memóriakezelést. A Java egy automatikus memóriakezelő rendszert használ, az úgynevezett a szemetes . Így nem szükséges memóriakezelési logikát implementálnunk az alkalmazásunkban. A Java memóriakezelés két fő részre oszlik:
JVM memóriastruktúra
A JVM különféle futásidejű adatterületeket hoz létre egy kupacban. Ezeket a területeket a program végrehajtása során használják. A memóriaterületek megsemmisülnek, amikor a JVM kilép, míg az adatterületek megsemmisülnek, amikor a szál kilép.
Módszer terület
A Method Area a kupacmemória része, amely meg van osztva az összes szál között. Akkor jön létre, amikor a JVM elindul. Az osztálystruktúra, a szuperosztálynév, az interfésznév és a konstruktorok tárolására szolgál. A JVM a következő típusú információkat tárolja a metódus területén:
- Egy típus teljesen minősített neve (pl.: String)
- A típus módosítói
- Írja be a közvetlen szuperosztály nevét
- A szuper interfészek teljes képzésű neveinek strukturált listája.
Halom terület
A kupac a tényleges objektumokat tárolja. Akkor jön létre, amikor a JVM elindul. A felhasználó szükség esetén vezérelheti a kupacot. Lehet fix vagy dinamikus méretű. Ha új kulcsszót használ, a JVM egy példányt hoz létre az objektumhoz egy kupacban. Míg az adott objektum hivatkozása a veremben tárolódik. Minden futó JVM-folyamathoz csak egy kupac létezik. Amikor a kupac megtelik, összegyűjtik a szemetet. Például:
StringBuilder sb= new StringBuilder();
A fenti utasítás létrehozza a StringBuilder osztály objektumát. Az objektum a kupachoz, az sb hivatkozás pedig a veremhez rendel hozzá. A kupac a következő részekre oszlik:
- Fiatal generáció
- Túlélő tér
- Régi generáció
- Állandó generáció
- Kód gyorsítótár
Referencia típus
Négyféle hivatkozás létezik: Erős , Gyenge , Puha , és Fantom referencia . A hivatkozások típusai között az a különbség, hogy az általuk hivatkozott kupacban lévő objektumok különböző kritériumok szerint jogosultak szemétgyűjtésre.
Erős hivatkozás: Nagyon egyszerű, mivel a napi programozásunk során használjuk. Minden olyan objektum, amelyhez Erős hivatkozás kapcsolódik, nem jogosult szemétgyűjtésre. Erős hivatkozást hozhatunk létre a következő állítás használatával:
StringBuilder sb= new StringBuilder();
Gyenge referencia: A következő szemétgyűjtési folyamat után nem éli túl. Ha nem vagyunk biztosak abban, hogy mikor kérik újra az adatokat. Ebben az állapotban gyenge hivatkozást tudunk létrehozni rá. Abban az esetben, ha a szemétgyűjtő feldolgozza, tönkreteszi az objektumot. Amikor újra megpróbáljuk lekérni az objektumot, null értéket kapunk. -ben van meghatározva java.lang.ref.WeakReference osztály. Gyenge hivatkozást készíthetünk a következő utasítás használatával:
WeakReference reference = new WeakReference(new StringBuilder());
Lágy referencia: A rendszer összegyűjti, ha az alkalmazás memóriája kezd fogyni. A szemétgyűjtő nem gyűjti össze a lágyan elérhető tárgyakat. Az összes puha hivatkozott objektum összegyűjtésre kerül, mielőtt OutOfMemoryError-t adna ki. Lágy hivatkozást a következő utasítás használatával hozhatunk létre:
SoftReference reference = new SoftReference(new StringBuilder());
Fantom referencia: ben kapható java.lang.ref csomag. -ben van meghatározva java.lang.ref.PhantomReference osztály. Azokra az objektumokra, amelyeknek csak fantomhivatkozása van, összegyűjthető, amikor a szemétgyűjtő gyűjteni akar. Fantomhivatkozást a következő utasítással hozhatunk létre:
PhantomReference reference = new PhantomReference(new StringBuilder());
Stack terület
A veremterület akkor jön létre, amikor egy szál jön létre. Lehet fix vagy dinamikus méretű. A veremmemória szálanként van lefoglalva. Adatok és részeredmények tárolására szolgál. Hivatkozásokat tartalmaz kupac objektumokra. Magát az értéket is tartalmazza, nem pedig a kupacból származó objektumra való hivatkozást. A veremben tárolt változók bizonyos láthatósággal rendelkeznek, amelyet hatókörnek neveznek.
Halmozott keret: A veremkeret egy adatstruktúra, amely a szál adatait tartalmazza. A száladatok a szál állapotát jelentik az aktuális metódusban.
- Részleges eredmények és adatok tárolására szolgál. Ezenkívül dinamikus linkelést, metódusok szerinti értékek visszaadását és kiküldési kivételeket is végrehajt.
- Amikor egy metódus meghív, egy új keret jön létre. Megsemmisíti a keretet, amikor a metódus meghívása befejeződik.
- Minden keret saját helyi változótömböt (LVA), operandusvermet (OS) és keretadatokat (FD) tartalmaz.
- Az LVA, az OS és az FD mérete a fordításkor meghatározott.
- Egy adott vezérlési szál bármely pontján csak egy keret (a végrehajtási módszer kerete) aktív. Ezt a keretet aktuális keretnek nevezzük, metódusát pedig aktuális módszernek. A metódus osztályát aktuális osztálynak nevezzük.
- A keret leállítja az aktuális metódust, ha a metódusa egy másik metódust hív meg, vagy ha a metódus befejeződik.
- A szál által létrehozott keret az adott szálhoz lokális, és nem hivatkozhat rá más szál.
Natív Method Stack
C stack néven is ismert. Ez egy verem a Javatól eltérő nyelven írt natív kódhoz. A Java Native Interface (JNI) meghívja a natív veremet. A natív verem teljesítménye az operációs rendszertől függ.
PC-regiszterek
Minden szálhoz tartozik egy programszámláló (PC) regiszter. A PC-regiszter tárolja a visszatérési címet vagy egy natív mutatót. Tartalmazza a jelenleg végrehajtott JVM utasítások címét is.
A szemétgyűjtő munkája
Szemétgyűjtő áttekintése
Amikor egy program Java nyelven fut, különböző módokon használja a memóriát. A kupac az emlékezet egy része, ahol a tárgyak élnek. Ez az egyetlen memóriarész, amely részt vesz a szemétgyűjtési folyamatban. Szemétgyűjtő kupacnak is nevezik. Minden szemétszállítás gondoskodik arról, hogy a kupacban a lehető legtöbb szabad hely legyen. A szemétgyűjtő feladata a nem elérhető objektumok megtalálása és törlése.
multiplexer
Objektum kiosztás
Amikor egy objektum lefoglal, a JRockit JVM ellenőrzi az objektum méretét. Különbséget tesz kis és nagy tárgyak között. A kis és nagy méret a JVM verziótól, a kupac méretétől, a szemétgyűjtési stratégiától és a használt platformtól függ. Egy objektum mérete általában 2 és 128 KB között van.
A kis objektumokat a Thread Local Area (TLA) tárolja, amely a kupac szabad darabja. A TLA nem szinkronizál más szálakkal. Amikor a TLA megtelik, új TLA-t kér.
Másrészt a nagy objektumok, amelyek nem férnek el a TLA-ban, közvetlenül a kupacba kerülnek. Ha egy szál a fiatal helyet használja, akkor közvetlenül a régi helyen tárolja. A nagy objektum nagyobb szinkronizálást igényel a szálak között.
Mit jelent a Java Garbage Collector?
A JVM vezérli a szemétgyűjtőt. A JVM dönti el, hogy mikor kell elvégezni a szemétgyűjtést. A JVM-től is kérhetjük a szemétszállító működtetését. De semmilyen feltétel nem garantálja, hogy a JVM megfelel. A JVM futtatja a szemétgyűjtőt, ha azt érzékeli, hogy kevés a memória. Amikor Java program kéri a szemétgyűjtőt, a JVM általában rövid időn belül teljesíti a kérést. Nem biztosítja a kérések elfogadását.
A lényeg, hogy megértsük, hogy mikor válik egy objektum szemétszállításra alkalmassá? '
Minden Java programnak több szála van. Minden szálnak megvan a maga végrehajtási verem. A Java programban van egy szál, amely egy main() metódus. Most már azt mondhatjuk, hogy egy objektum akkor jogosult a szemétgyűjtésre, ha egyetlen élő szál sem fér hozzá. A szemétgyűjtő az objektumot törölhetőnek tekinti. Ha egy programnak van egy referenciaváltozója, amely egy objektumra hivatkozik, ez a referenciaváltozó elérhető az élő szál számára, akkor ezt az objektumot ún. elérhető .
Itt felmerül a kérdés, hogy Kifogyhat a memória egy Java alkalmazásból? '
A válasz igen. A szemétgyűjtő rendszer megkísérli az objektumokat a memóriából gyűjteni, amikor azok nincsenek használatban. Ha azonban sok élő objektumot karbantart, a szemétgyűjtés nem garantálja, hogy elegendő memória áll rendelkezésre. Csak a rendelkezésre álló memória lesz hatékonyan kezelve.
A szemétgyűjtés típusai
A szemétszállításnak öt fajtája létezik:
Mark and Sweep algoritmus
A JRockit JVM a mark, and sweep algoritmust használja a szemétgyűjtés végrehajtásához. Két fázist tartalmaz, a jelölési fázist és a sweep fázist.
Mark fázis: A szálakból, natív leírókból és más GC gyökérforrásokból elérhető objektumok élőként vannak megjelölve. Minden objektumfának egynél több gyökérobjektuma van. A GC gyökér mindig elérhető. Tehát minden olyan objektum, amelynek a gyökerében van egy szemétgyűjtő gyökér. Azonosítja és megjelöli az összes használatban lévő objektumot, a maradék pedig szemétnek tekinthető.
Sweep fázis: Ebben a fázisban a kupac áthaladva megkeresi az élő objektumok közötti rést. Ezek a hiányosságok a szabad listán vannak rögzítve, és elérhetők az új objektumok kiosztásához.
A mark and sweep két továbbfejlesztett változata létezik:
Egyidejű Mark and Sweep
Lehetővé teszi, hogy a szálak továbbra is futhassanak a szemétgyűjtés nagy része alatt. A következő típusú jelölések léteznek:
Párhuzamos Mark and Sweep
A rendszerben rendelkezésre álló összes CPU-t felhasználja a szemétgyűjtés lehető leggyorsabb elvégzéséhez. Párhuzamos szemétgyűjtőnek is nevezik. A szálak nem futnak le, amikor a párhuzamos szemétgyűjtés végrehajtódik.
A Mark and Sweep előnyei
javascript letöltés
- Ez egy visszatérő folyamat.
- Ez egy végtelen hurok.
- Az algoritmus végrehajtása során további általános költségek nem megengedettek.
A Mark and Sweep hátrányai
- Leállítja a normál programfuttatást, miközben a szemétgyűjtő algoritmus fut.
- Egy programon többször lefut.