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.

  • 🧠 JVM memória elrendezés: Java A memória Heap-re van osztva az objektumok számára, Stack-re a metóduskeretek és a lokális változók számára, valamint dedikált területekre a bájtkód és a statikus adatok számára.
  • ???? Stack vs. Heap: A verem keretek az „utoljára be, először ki” sorrendet követik, és primitíveket, valamint referenciákat tárolnak, míg a halom (Heap) az „új” operátorral létrehozott összes objektumot tartalmazza.
  • ♻️ Szemétgyüjtés: A szemétgyűjtő tracks elérhetőséget biztosít referencialáncokon keresztül, és automatikusan visszanyer memóriát azoktól az objektumoktól, amelyeket egyetlen szál sem tud elérni.
  • Modern gyűjtők: Az éles munkaterhelések egyre inkább a G1, a ZGC és a Shenandoah protokollokra támaszkodnak a több gigabájtos heap-ekben történő, rövid szünetű adatgyűjtéshez.
  • 🧪 Gyakorlati példa: Egy lépésről lépésre bemutatott Student osztályútmutató bemutatja, hogy mikor válnak a referenciák gyűjthetővé, és hogyan szabadítja fel a referenciák nullázása az alapul szolgáló objektumot.

Memóriakezelés be Java

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:

  1. Halom
  2. Stack
  3. Code
  4. 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.

Java Stack és Heap

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

Java Stack és Heap

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

Java Stack és Heap

Java Stack és Heap

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

Java Stack és Heap

Java Stack és Heap

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.

Java Stack és Heap

A ref referenciaváltozó a Stackben jön létre az m3 keretén belül.

Java Stack és Heap

Az értékadó operátor a referenciaváltozót a Heap objektumára állítja be.

Java Stack és Heap

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.

Java Stack és Heap

Az m3 metódus kerete kiürül a veremből.

Java Stack és Heap

Mivel a referenciaváltozó már nem a Heap-en lévő objektumra mutat, az objektum jogosulttá válik a szemétgyűjtésre.

Java Stack és Heap

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

Java Stack és Heap

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.

 Szemétgyűjtő mechanizmus

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.

Szemétgyűjtő mechanizmus

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.

 Szemétgyűjtő mechanizmus

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.

 Ismerje meg a szemétgyűjtőt

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.

Hogyan lehet törölni egy objektumot Java

GYIK

A Stack (Stack) szálanként Utoljára be, Elsőként ki sorrendben tárolja a metóduskereteket, a lokális változókat és a referenciákat. A Heap (Heap) az új metódussal létrehozott összes objektumot tárolja, és a szálak között meg van osztva, ezért kezeli a Garbage Collector (Garbage Collector).

A Garbage Collector a GC gyökereiből kiinduló referencialáncokat, például aktív szálakat és statikus mezőket vizsgálja. Minden olyan objektumot, amely nem érhető el egy gyökérből, elérhetetlennek tekint, és a következő gyűjtési ciklus során jogosulttá válik a visszanyerésre.

A Fiatal Generáció rövid életű objektumokat tárol az Eden és a Túlélő terekben. Az Öreg Generáció olyan objektumokat tárol, amelyek több gyűjteményt is túlélnek. A Metatér egy natív memóriájú régió, amely az osztály metaadatait tárolja, és a régebbi PermGen-t váltotta fel a következőben: Java 8.

A G1 az alapértelmezett, és a legtöbb több gigabájtos heap-eken futó munkaterheléshez illik. A ZGC és a Shenandoah a milliszekundum alatti szüneteket célozza meg nagyon nagy heap-eken, és jó választás a késleltetésre érzékeny szolgáltatásokhoz, amelyek a következőn futnak: Java 17 vagy újabb.

Állíts minden objektumra mutató hivatkozást nullra, vagy hagyd, hogy a hivatkozások kiessenek a hatókörből, amikor a Stack kereteik előkerülnek. Amint nem éri el az objektumot élő hivatkozás, a Garbage Collector visszaveszi a Heap memóriáját.

Igen. A mesterséges intelligencia által vezérelt hangolóeszközök elemzik a GC-naplókat, az allokációs arányokat és szüneteltetik a hisztogramokat, hogy javaslatokat tegyenek a heap-méretekre, a gyűjtőjelzőkre és a Young Generation arányokra. Lerövidítik a visszacsatolási ciklust a manuális hangoláshoz képest, különösen a G1, ZGC és Shenandoah munkaterhelések esetében.

A mesterséges intelligencia alapú megfigyelhetőségi platformok heap dump-okat és élő metrikákból dolgoznak fel, majd a megőrzött objektumgráfokat klaszterezik a gyanús osztályok és referencialáncok megjelölésére. Ez gyorsabban felszínre hozza a szivárgási jelölteket, mint a manuális heap elemzés, és segít a csapatoknak a kiváltó ok meghatározásában éles környezetben.

Foglald össze ezt a bejegyzést a következőképpen: