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:
- 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
- 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
- Á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:
- 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
- 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
- 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.
- 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éter | Verem memória | Halomtér |
---|---|---|
Alkalmazás | A verem részenként, egyenként használható a szál végrehajtása során | A teljes alkalmazás futás közben használja a Heap helyet |
Méret | A Stack méretkorlátjai az operációs rendszertől függenek, és általában kisebb, mint a Heap | A Halomra nincs méretkorlátozás |
Tárolás | Csak a Heap Space-ben létrehozott primitív változókat és objektumokra való hivatkozásokat tárolja | Az összes újonnan létrehozott objektum itt van tárolva |
Rendelés | A Last-in First-out (LIFO) memória-allokációs rendszer segítségével érhető el | Ez 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. |
Élet | Verem memória csak addig létezik, amíg az aktuális módszer fut | Halom hely létezik, amíg az alkalmazás fut |
Hatékonyság | A halomhoz képest sokkal gyorsabban lehet kiosztani | Lassúbb a felosztás a veremhez képest |
Kiosztás / elosztás | Ez a memória automatikusan kiosztásra és szétosztásra kerül, ha egy metódust meghívunk és visszaküldünk | Halom 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.