logo

Memóriakezelés Java nyelven

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 szemétgyűjtő munkája

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.

Memóriakezelés Java nyelven

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:

    Soros GC:A mark and sweeps megközelítést használja fiatal és idős generációk számára, ami kisebb és nagyobb GC.Párhuzamos GC:Hasonló a soros GC-hez, kivéve, hogy N szálat (a rendszerben lévő CPU magok száma) hoz létre a fiatal generációs szemétgyűjtéshez.Párhuzamos régi GC:Hasonló a párhuzamos GC-hez, kivéve, hogy mindkét generációhoz több szálat használ.Egyidejű Mark Sweep (CMS) gyűjtő:Szemétszállítást végez az öreg generáció számára. Korlátozhatja a szálak számát a CMS-gyűjtőben XX:ParalleCMSThreads=JVM opció . Egyidejű alacsony szünet gyűjtőként is ismert.G1 szemétgyűjtő:Java 7-ben vezették be. Célja a CMS gyűjtő lecserélése. Ez egy párhuzamos, párhuzamos és CMS-gyűjtő. Nincs fiatal és idős generációs tér. A kupacot több egyenlő méretű kupacra osztja. Először a kevesebb élő adattal rendelkező régiókat gyűjti össze.

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ő.

Memóriakezelés Java nyelven

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 Párhuzamos Mark and Sweep

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:

    Kezdeti jelölés:Azonosítja az élő objektumok gyökérkészletét. A szálak szüneteltetése közben történik.Egyidejű jelölés:Ebben a jelölésben a gyökérkészletből származó hivatkozást követik. Megkeresi és megjelöli a többi élő objektumot egy kupacban. A szál futása közben történik.Előtisztítási jelölés:Azonosítja az egyidejű jelöléssel végrehajtott változtatásokat. Egyéb élő objektumok megjelölve és megtalálva. Ez a szálak futása közben történik.Végső jelölés:Azonosítja az előtisztítási jelöléssel végrehajtott változtatásokat. Egyéb élő objektumok megjelölve és megtalálva. A szálak szüneteltetése közben történik.

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.