Verem memória és halom helyet Java-ban

1. Bemutatkozás

Az alkalmazás optimális futtatásához a JVM felosztja a memóriát verem és halom memóriára. Amikor új változókat és objektumokat deklarálunk, hívjon új metódust, deklarálja a Húr vagy hasonló műveleteket hajt végre, a JVM kijelöli ezeknek a műveleteknek a memóriát akár a verem memóriájából, akár a kupac térből.

Ebben az oktatóanyagban ezeket a memóriamodelleket tárgyaljuk. Néhány legfontosabb különbséget felsorolunk közöttük, a RAM-ban való tárolás módjában, az általuk kínált funkciókban és a használatuk helyében.

2. Rakd össze a memóriát a Java-ban

A Java memória memória statikus memória-allokációra és egy szál végrehajtására szolgál. Olyan primitív értékeket tartalmaz, amelyek specifikusak egy módszerre, és hivatkozásokat mutatnak a kupacban lévő objektumokra, amelyekre a módszer hivatkozik.

Ehhez a memóriához Last-In-First-Out (LIFO) sorrendben férhet hozzá. Amikor új metódust hívnak meg, egy új blokk jön létre a verem tetején, amely az adott módszerre jellemző értékeket tartalmaz, mint például a primitív változókat és az objektumokra való hivatkozásokat.

Amikor a metódus befejezi a végrehajtást, a megfelelő veremkeret kiürül, a folyamat visszamegy a hívási módszerhez, és szabad hely áll rendelkezésre a következő módszer számára.

2.1. A verem memória főbb jellemzői

Az eddig tárgyaltakon kívül a verem memória néhány további jellemzője:

  • Növekszik és zsugorodik, ahogy új módszereket hívnak és viszonoznak
  • A veremben lévő változók csak addig léteznek, amíg az őket létrehozó módszer fut
  • Automatikusan kiosztásra és felosztásra kerül, amikor a módszer befejezi a végrehajtást
  • Ha ez a memória megtelt, a Java dob java.lang.StackOverFlowError
  • Ehhez a memóriához gyors a hozzáférés a halom memóriához képest
  • Ez a memória szálbiztos, mivel minden szál a saját veremében működik

3. Halomtér Java-ban

A Java-ban lévő halom helyet dinamikus memória-allokációra használják Java objektumok és JRE osztályok számára futás közben. Az új objektumok mindig a halom térben jönnek létre, és az ezekre az objektumokra való hivatkozások a verem memóriájában tárolódnak.

Ezek az objektumok globális hozzáféréssel rendelkeznek, és az alkalmazás bárhonnan elérhetők.

Ez a memóriamodell tovább oszlik generációknak nevezett kisebb részekre, ezek a következők:

  1. Fiatal generáció - itt allokálják és öregítik az összes új objektumot. Kisebb szemétgyűjtés történik, amikor ez megtelt
  2. Régi vagy bérelt generáció - itt tárolják a régóta fennmaradt tárgyakat. Ha az objektumokat a fiatal generáció tárolja, akkor az objektum korának küszöbértéke kerül meghatározásra, és amikor ezt a küszöböt eléri, az objektum a régi generációhoz kerül
  3. Állandó Generáció - ez a futásidejű osztályok JVM metaadataiból és az alkalmazási módszerekből áll

Ezeket a különböző részeket ez a cikk is tárgyalja - Különbség a JVM, a JRE és a JDK között.

Mindig manipulálhatjuk a halom memória méretét a követelményeknek megfelelően. További információért keresse fel ezt a linkelt Baeldung cikket.

3.1. A Java halom memória főbb jellemzői

Az eddig tárgyaltakon kívül a halomtér néhány további jellemzője a következő:

  • Bonyolult memóriakezelési technikákon keresztül érhető el, amelyek magukban foglalják a Young Generation, Old or Tenured Generation és az állandó generációt
  • Ha a kupacterület megtelt, a Java dob java.lang.OutOfMemoryError
  • Ehhez a memóriához viszonylag lassabban lehet hozzáférni, mint a verem memóriához
  • A memóriával ellentétben ez a memória nem kerül automatikusan felosztásra. Szüksége van a Garbage Collector-ra, hogy felszabadítsa a fel nem használt objektumokat a memóriafelhasználás hatékonyságának megőrzése érdekében
  • A veremtől eltérően a kupac nem szálbiztonságos, és a kód megfelelő szinkronizálásával kell védeni

4. Példa

Az eddig tanultak alapján elemezzünk egy egyszerű Java kódot, és értékeljük, hogyan kezelik itt a memóriát:

osztály Személy {int id; Karakterlánc neve; public Person (int id, String name) {this.id = id; ez.név = név; }} public class PersonBuilder {private static Person buildPerson (int id, String name) {return new Person (id, név); } public static void main (Karakterlánc [] args) {int id = 23; Karakterlánc neve = "John"; Személy személy = null; személy = buildPerson (id, név); }}

Elemezzük ezt lépésről lépésre:

  1. Belépéskor a fő() módszerrel, a verem memóriájában helyet hoznának létre a primitívek és a módszer referenciáinak tárolására
    • Az egész szám primitív értéke id közvetlenül a verem memóriájában lesz tárolva
    • A referencia változó személy típusú Személy a verem memóriájában is létrejön, amely a halom tényleges objektumára mutat
  2. A paraméterezett konstruktor hívása Személy (int, húr) tól től fő() további memóriát oszt ki az előző verem tetején. Ez tárolja:
    • A ez a verem memóriájában található hívó objektum objektum hivatkozása
    • A primitív érték id a verem memóriájában
    • A referencia változó Húr érv név amely a halom memóriában található string készlet tényleges karakterláncára mutat
  3. A fő- módszer tovább hívja a buildPerson () statikus módszer, amelynek további kiosztása a verem memóriájában történik az előző mellett. Ez a változókat ismét a fent leírt módon tárolja.
  4. Azonban az újonnan létrehozott objektumra személy típusú Személy, az összes példányváltozó a halom memóriában lesz tárolva.

Ezt az allokációt az alábbi ábra magyarázza:

5. Összefoglalás

Mielőtt befejeznénk ezt a cikket, gyorsan foglaljuk össze a verem memória és a kupac tér közötti különbségeket:

ParaméterVerem memóriaHalomtér
AlkalmazásA verem részenként, egyenként használható a szál végrehajtása soránA teljes alkalmazás futás közben használja a Heap helyet
MéretA Stack méretkorlátjai az operációs rendszertől függenek, és általában kisebb, mint a HeapA Halomra nincs méretkorlátozás
TárolásCsak a Heap Space-ben létrehozott primitív változókat és objektumokra való hivatkozásokat tároljaAz összes újonnan létrehozott objektum itt van tárolva
RendelésA Last-in First-out (LIFO) memória-allokációs rendszer segítségével érhető elEz a memória komplex memóriakezelési technikákon keresztül érhető el, amelyek magukban foglalják a fiatal generációt, az öreg vagy tenurált generációt és az állandó generációt.
ÉletVerem memória csak addig létezik, amíg az aktuális módszer futHalom hely létezik, amíg az alkalmazás fut
HatékonyságA halomhoz képest sokkal gyorsabban lehet kiosztaniLassúbb a felosztás a veremhez képest
Kiosztás / elosztásEz a memória automatikusan kiosztásra és szétosztásra kerül, ha egy metódust meghívunk és visszaküldünkHalom teret osztanak ki, amikor új objektumokat hoz létre és oszt ki a Gargabe Collector, amikor már nem hivatkoznak rájuk.

6. Következtetés

A verem és a halom kétféle módon osztja el a Java a memóriát. Ebben a cikkben megértettük, hogyan működnek és mikor kell őket használni jobb Java programok fejlesztéséhez.

Ha többet szeretne megtudni a Java memóriakezeléséről, tekintse meg ezt a cikket itt. Megbeszéltük a JVM szemétgyűjtőjét is, amelyet ebben a cikkben röviden áttekintünk.