Memóriakezelés be Java
⚡ Okos összefoglaló
Memóriakezelés be Java elmagyarázza, hogyan osztja fel a JVM a futásidejű memóriát a Stack, Heap és ... között. Code, és statikus régiók, az objektumhivatkozások áramlása a metódushívások során, és hogy a Garbage Collector hogyan nyeri vissza az elérhetetlen objektumokat, hogy az alkalmazások stabilak és memóriaszivárgástól mentesek maradjanak.

Mi a verem memória? Java?
Stack memória beépítése Java a JVM memória azon régiója, amely az egyes szálak metóduskereteit, lokális változóit és referenciaváltozóit tárolja. A Stackhez (stack) mindig Utoljára be-először ki sorrendben (Utoljára be-először ki) érünk el, tehát a legutóbb meghívott metódus kerül felülre, és a lokális változói a kerettel együtt kerülnek be- és kitöltésbe.
Minden szál a Java A virtuális gép saját Stacket kap, amely a metódushívásokat elkülönítve és szálbiztosan kezeli. Az olyan primitív lokálok, mint az int, a boolean és a double, közvetlenül a kereten belül helyezkednek el, míg a Stacken tárolt objektumhivatkozások a Heapen lefoglalt objektumokra mutatnak.
Mi a halom memória? Java?
A heap memória a megosztott JVM régió, amely minden elemet tárol. Java az új operátorral létrehozott objektumot és tömböt, valamint az ezekhez az objektumokhoz tartozó hivatkozási változókat példánymezőként. A Stackkel ellentétben a Heap az összes szál között megosztott, ezért az objektumhozzáférés gyakran szinkronizálást igényel.
A Heap az a terület, amelyet a Garbage Collector kezel. A modern HotSpot JVM-ek a Heap-et egy Young Generation-re osztják a rövid életű objektumok számára és egy Old Generation-re a hosszú életű objektumok számára, az osztály metaadatait pedig egy különálló natív régióban, a Metaspace-ben tárolják.
Memóriakiosztás be Java
Memóriakiosztás be Java az a folyamat, amelynek során a JVM virtuális memóriaterületeket különít el a változók, valamint az osztályok és struktúrák példányai számára a program végrehajtása során. A memória nem kerül lefoglalásra egy objektumhoz a deklaráció során; csak egy referencia jön létre. A tényleges objektumlefoglalás a new operátoron keresztül történik, így minden objektum a Heap-en található.
Az Java A memóriaelosztás a következő részekre oszlik:
- Halom
- Stack
- Code
- Statikus
Ez a memóriafelosztás a futási környezet hatékony kezeléséhez szükséges.
- Az Code szakasz tartalmazza a lefordított bájtkódot.
- Az Stack részlegboltok metódusok, lokális változók és referenciaváltozók.
- Az Halom szakasz tartalmazza objektumok és példánymezőként tárolt referenciaváltozókat is tartalmazhat.
- Az Statikus szakasz tartja statikus adatok és statikus metódusok minden példányban megosztva.
Különbség a helyi és a példányváltozó között
Ha megértjük, hogy az egyes változótípusok hol helyezkednek el a JVM-ben, az segít megérteni a Stack és Heap viselkedését. példány változó deklarálják egy osztályon belül, de bármely metóduson kívül, és a Halomon él, mint a tárgyának része.
class Student{ int num; // num is instance variable public void showData{}
A helyi változó deklarálják egy metóduson belül, beleértve a metódus argumentumait is, és az aktív kereten belüli Stacken található.
public void sum(int a){ int x = a + 3; // a, x are local variables }
Különbség a verem és a kupac között
A Stack és a Heap különböző problémákat old meg a JVM-en belül. A Stack minden szálnak gyors, determinisztikus allokációt biztosít a metódus hatóköréhez kötött rövid életű adatokhoz, míg a Heap egy megosztott régiót biztosít a hosszú életű objektumok számára, amelyre bármely szál hivatkozhat. Az alábbi rövid videó összefoglalja az összehasonlítást a következő bemutató előtt.
Kattints itt ha a videó nem érhető el
A Stack és a Heap együttműködésének megértéséhez vegyünk egy main metódust, amely meghívja az m1 metódust.
public void m1{ int x = 20; }
A JVM Stackben egy keret jön létre az m1 metódushoz.
Az m1-ben található x változó szintén létrejön az m1 keretrendszerében a Stackben, ahogy az az alábbi képen is látható.
Az m1 metódus ezután meghívja az m2 metódust. A Stackben egy új keret jön létre az m2 metódushoz az m1 metódus kerete fölé.
A b és c lokális változók szintén létrejönnek az m2 keretén belül a Stackben.
public void m2(int b){ boolean c; }
Ezután az m2 meghívja az m3 metódust. Ismét létrehozunk egy keretet az m3 számára a Stack tetején, ahogy az alább látható.
Tegyük fel, hogy az m3 metódus létrehoz egy objektumot az Account osztály számára, amelynek két objektuma van: Példányváltozók int p és int q.
class Account { int p; int q; }
Itt az m3 metódus kódja.
public void m3(){ Account ref = new Account(); // more code }
A new Account() utasítás egy Account objektumot hoz létre a Heap-en.
A ref referenciaváltozó a Stackben jön létre az m3 keretén belül.
Az értékadó operátor a referenciaváltozót a Heap objektumára állítja be.
Miután a metódus végrehajtása befejeződött, a vezérlés visszatér a hívó metódushoz, ami ebben az esetben az m2 metódus.
Az m3 metódus kerete kiürül a veremből.
Mivel a referenciaváltozó már nem a Heap-en lévő objektumra mutat, az objektum jogosulttá válik a szemétgyűjtésre.
Miután az m2 metódus befejeződött, kikerül a veremből, és az összes változója elérhetetlenné válik. Ugyanez történik az m1 metódussal is, és végül a vezérlés visszatér a fő metódushoz.
Mi van akkor, ha egy objektum egy másik referenciát tartalmaz példányváltozóként?
public static void main(String args[]) { A parent = new A(); // more code } class A { B child = new B(); int e; } class B { int c; int d; }
Ebben az esetben a referenciaváltozó gyermeke a Heap-en található az A objektum részeként, és viszont a saját B objektumára mutat, ahogy az alább látható.
Miben található a szemétgyűjtés? Java?
Szemétgyűjtés itt Java az a folyamat, amelynek során a JVM automatikusan memóriakezelést végez. A szemétgyűjtő megkeresi azokat az objektumokat, amelyek már nem érhetők el élő hivatkozásokból, és visszanyeri a memóriájukat. A dinamikus memóriafoglalás az new operátoron keresztül történik, és a memória lefoglalt marad, amíg a program már nem tartalmaz hivatkozást az objektumra.
Amikor már nincsenek referenciák, az objektumra már nincs szükség, és az általa elfoglalt memória visszanyerhető. Nincs explicit szükség egy objektum megsemmisítésére, mert Java automatikusan kezeli az üzletelosztást a Garbage Collectoron keresztül.
A mögötte álló technika az úgynevezett SzemétgyüjtésAzok a programok, amelyek nem tudnak memóriát felszabadítani, végül összeomlanak, amikor már nincs mit lefoglalni. Az ilyen programokról azt mondják, hogy a memória szivárog. Szemétgyűjtés itt Java automatikusan fut a program teljes élettartama alatt, ami leveszi a terhet a manuális felszabadításról és csökkenti a szivárgások kockázatát.
C nyelven ezzel szemben a programozó felelős a free() függvénnyel dinamikusan lefoglalt memória felszabadításáért. Itt történik a feladat. Java A memóriakezelés komoly előnyöket kínál.
A modern HotSpot JVM-ek számos, különböző munkaterhelésekhez hangolt Garbage Collectort tartalmaznak. Az alapértelmezett G1 Garbage Collector kiegyensúlyozott átviteli és szüneteltetési időket céloz meg több gigabájtos heap-eken. A ZGC és a Shenandoah ezredmásodperc alatti szüneteket céloz meg nagyon nagy heap-eken, ami miatt...trackésleltetésérzékeny szolgáltatásokhoz. A megfelelő gyűjtő kiválasztása és a Fiatal Generáció, Régi Generáció és Metatér méretének finomhangolása alapvető készség a Java előadóművészeti munka.
Jegyzet: Minden objektum a memória Heap szakaszában jön létre, amely a Garbage Collector által kezelt régió.
Példa: Tanulja meg a szemétgyűjtő mechanizmust Java
Ez az útmutató bemutatja, hogy mikor válnak a hivatkozások jogosulttá a Garbage Collection funkcióra egy egyszerű programban.
Step 1) Másolja be a következő kódot egy szerkesztőbe.
class Student{ int a; int b; public void setData(int c,int d){ a=c; b=d; } public void showData(){ System.out.println("Value of a = "+a); System.out.println("Value of b = "+b); } public static void main(String args[]){ Student s1 = new Student(); Student s2 = new Student(); s1.setData(1,2); s2.setData(3,4); s1.showData(); s2.showData(); //Student s3; //s3=s2; //s3.showData(); //s2=null; //s3.showData(); //s3=null; //s3.showData(); } }
Step 2) Mentse el, fordítsa le és futtassa a kódot. Ahogy az ábrán látható, két objektum és két referenciaváltozó jön létre.
Step 3) Töröld ki a 20., 21. és 22. sorok kommentjét. Mentsd el, fordítsd le és futtasd a kódot.
Step 4) Amint az alábbi ábrán látható, két referenciaváltozó most ugyanarra az objektumra mutat.
Step 5) Töröld ki a 23. és 24. sorok kommentjét. Mentsd el, fordítsd le és futtasd a kódot.
Step 6) Amint az alább látható, az s2 null értékűvé válik, de az s3 továbbra is az objektumra mutat, így az objektum még nem jogosult a szemétgyűjtésre.
Step 7) Töröld ki a 25. és 26. sorok kommentjét. Mentsd el, fordítsd le és futtasd a kódot.
Step 8) Ezen a ponton már nem mutatnak hivatkozások az objektumra, így az alkalmassá válik a szemétgyűjtésre. A szemétgyűjtő eltávolítja a memóriából, és nincs mód a visszaállítására.
Hogyan töröljünk egy objektumot a Java?
Java nem biztosít manuális törlési operátort, így a standard megközelítés az objektumra mutató összes hivatkozás eltávolítása, hogy a Garbage Collector visszanyerhesse azt.
1) Ahhoz, hogy egy objektum alkalmas legyen a szemétgyűjtésre, minden rá mutató referenciaváltozóhoz rendeljünk null értéket.
2) Az primitív típusok nem objektumok, így nem rendelhetők null értékhez. A tárhelyük automatikusan visszanyerésre kerül, amikor a környező Stack keretet felszabadítjuk.


















