Minnehåndtering i Java

⚡ Smart oppsummering

Minnehåndtering i Java forklarer hvordan JVM-en deler runtime-minnet mellom Stack, Heap, Code, og statiske regioner, hvordan objektreferanser flyter under metodekall, og hvordan Garbage Collector gjenvinner utilgjengelige objekter slik at applikasjoner forblir stabile og fri for minnelekkasjer.

  • 🧠 JVM-minneoppsett: Java minnet er delt inn i Heap for objekter, Stack for metoderammer og lokale variabler, pluss dedikerte områder for bytekode og statiske data.
  • 📚 Stabel vs. Haug: Stablerammer følger rekkefølgen «sist inn, først ut» og lagrer primitiver og referanser, mens heapen inneholder alle objekter som er opprettet med den nye operatoren.
  • ♻️ Søppelsamling: Søppelsamleren tracks-tilgjengelighet gjennom referansekjeder og gjenopptar automatisk minne fra objekter som ingen tråd kan nå.
  • Moderne samlere: Produksjonsarbeidsbelastninger er i økende grad avhengige av G1, ZGC og Shenandoah for innsamling med lav pause på tvers av heaps på flere gigabyte.
  • 🧪 Praktisk eksempel: En trinnvis gjennomgang av Student-klassen viser når referanser blir kvalifisert for innsamling og hvordan nullstilling av referanser frigjør det underliggende objektet.

Minnehåndtering i Java

Hva er stakkminne i Java?

Stable minne inn Java er området i JVM-minnet som lagrer metoderammer, lokale variabler og referansevariabler for hver tråd. Stacken aksesseres alltid i rekkefølgen sist inn, først ut, slik at den sist påkalte metoden ligger øverst, og dens lokale variabler pushes og poppes sammen med rammen.

Hver tråd i Java Virtuell maskin mottar sin egen Stack, som holder metodekalkall isolert og trådsikkert basert på design. Primitive lokale verdier som int, boolean og double befinner seg direkte inne i rammen, mens objektreferanser lagret på Stack peker til objekter allokert på Heap.

Hva er heapminne i Java?

Heapminne er den delte JVM-regionen som inneholder alle Java objekt og array opprettet med den nye operatoren, sammen med eventuelle referansevariabler som tilhører disse objektene som instansfelt. I motsetning til Stack deles Heap på tvers av alle tråder, og det er derfor objekttilgang ofte krever synkronisering.

Heapen er området som Garbage Collector administrerer. Moderne HotSpot JVM-er deler Heapen inn i en ung generasjon for kortlivede objekter og en gammel generasjon for langlivede objekter, med klassemetadata lagret i en separat, opprinnelig region kalt Metaspace.

Minnetildeling inn Java

Minnetildeling inn Java er prosessen der JVM setter av virtuelle minneområder for variabler og forekomster av klasser og strukturer under programutførelse. Minnet tildeles ikke et objekt ved deklarasjon; bare en referanse opprettes. Den faktiske objektallokeringen skjer gjennom den nye operatoren, slik at hvert objekt ligger på heapen.

Ocuco Java Minneallokering er delt inn i følgende seksjoner:

  1. heap
  2. Stable
  3. Code
  4. Statisk

Denne minnedelingen er nødvendig for effektiv styring av kjøretiden.

  • Ocuco Code seksjonen inneholder den kompilerte Bytecode.
  • Ocuco Stable seksjonsbutikker metoder, lokale variabler og referansevariabler.
  • Ocuco heap delen inneholder gjenstander og kan også inneholde referansevariabler som holdes som instansfelt.
  • Ocuco Statisk seksjonshold statiske data og statiske metoder delt på tvers av alle instanser.

Forskjellen mellom lokal og forekomstvariabel

Å forstå hvor hver type variabel befinner seg i JVM-en bidrar til å forklare Stack- og Heap-oppførselen. forekomstvariabel blir erklært innenfor en klasse, men utenfor enhver metode, og den bor på Haugen som en del av objektet sitt.

class Student{ 
int num; // num is instance variable 
public void showData{}

A lokal variabel blir erklært inne i en metode, inkludert metodeargumenter, og ligger på stakken inne i den aktive rammen.

public void sum(int a){

int x = a + 3;

// a, x are local variables

}

Forskjellen mellom Stack og Heap

Stack og Heap løser forskjellige problemer i JVM-en. Stack gir hver tråd rask, deterministisk allokering for kortlivede data knyttet til metodeomfang, mens Heap gir et delt område for objekter med lang levetid som enhver tråd kan referere til. Den korte videoen nedenfor oppsummerer kontrasten før gjennomgangen som følger.

Klikk her. hvis videoen ikke er tilgjengelig

For å se hvordan Stack og Heap samarbeider, kan du vurdere en hovedmetode som kaller metode m1.

public void m1{
int x = 20;
}

I JVM-stakken opprettes en ramme for metode m1.

Java Stack og heap

Variabelen x i m1 opprettes også i rammen for m1 på stakken, som vist på bildet nedenfor.

Java Stack og heap

Metode m1 kaller deretter metode m2. I stakken opprettes en ny ramme for m2 oppå rammen for m1.

Java Stack og heap

Java Stack og heap

De lokale variablene b og c opprettes også inne i rammen for m2 på stakken.

public void m2(int b){
boolean c;
}

Deretter kaller m2 metoden m3. Igjen opprettes en ramme for m3 øverst i stakken, som vist nedenfor.

Java Stack og heap

Java Stack og heap

La oss nå si at metode m3 oppretter et objekt for klassen Account, som har to instansvariabler int p og int q.

class Account {
    int p;
    int q;
}

Her er koden for metode m3.

public void m3(){
    Account ref = new Account();
    // more code
}

Uttrykket new Account() oppretter et objekt av typen Account på heapen.

Java Stack og heap

Referansevariabelen ref opprettes på stakken inne i rammen for m3.

Java Stack og heap

Tildelingsoperatoren får referansevariabelen til å peke til objektet på Heap-en.

Java Stack og heap

Når metoden er fullført, går kontrollen tilbake til den kallende metoden, som i dette tilfellet er metode m2.

Java Stack og heap

Rammen for metode m3 skylles ut av stakken.

Java Stack og heap

Siden referansevariabelen ikke lenger peker til objektet på Heap-en, blir det objektet kvalifisert for søppelinnsamling.

Java Stack og heap

Når metode m2 er ferdig, fjernes den fra stakken, og alle variablene blir utilgjengelige. Det samme skjer for metode m1, og til slutt går kontrollen tilbake til hovedmetoden.

Hva om et objekt har en annen referanse som sin instansvariabel?

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;
}

I dette tilfellet ligger referansevariabelen «child» på Heap-en som en del av A-objektet, og peker igjen til sitt eget B-objekt, som vist nedenfor.

Java Stack og heap

Hva er Garbage Collection i Java?

Søppeloppsamling i Java er prosessen der JVM-en utfører minnehåndtering automatisk. Garbage Collector finner objekter som ikke lenger er tilgjengelige fra noen live-referanse og gjenvinner minnet deres. Dynamisk minneallokering skjer gjennom den nye operatoren, og minnet forblir allokert til programmet ikke lenger har noen referanse til objektet.

Når det ikke lenger finnes noen referanser, anses objektet som ikke lenger nødvendig, og minnet det opptar kan gjenvinnes. Det er ikke noe eksplisitt behov for å ødelegge et objekt fordi Java håndterer deallokeringen automatisk gjennom søppeloppsamleren.

Teknikken bak dette er kjent som SøppelsamlingProgrammer som ikke klarer å frigjøre minne krasjer til slutt når det ikke er noe igjen å allokere. Slike programmer sies å ha minne lekker. Søppeloppsamling i Java kjører automatisk gjennom hele programmets levetid, noe som fjerner byrden med manuell deallokering og reduserer risikoen for lekkasjer.

I C, derimot, er programmereren ansvarlig for å frigjøre minne allokert dynamisk gjennom free()-funksjonen. Det er her Java Minnehåndtering gir en stor fordel.

Moderne HotSpot JVM-er leveres med flere Garbage Collectors som er innstilt for forskjellige arbeidsbelastninger. Standard G1 Garbage Collector sikter mot balansert gjennomstrømning og pausetider på heaps på flere gigabyte. ZGC og Shenandoah sikter mot pauser på under et millisekund på veldig store heaps, noe som gjør dem påtractiv for latenssensitive tjenester. Å velge riktig samler og finjustere størrelsene for den unge generasjonen, den gamle generasjonen og metaspace er en kjerneferdighet for Java fremføringsarbeid.

OBS: Alle objekter opprettes i Heap-delen av minnet, som er regionen Garbage Collector administrerer.

Eksempel: Å lære søppeloppsamlermekanismen i Java

Denne gjennomgangen viser når referanser blir kvalifisert for søppeltømming i et enkelt program.

Trinn 1) Kopier følgende kode inn i en editor.

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();
  }
}

Trinn 2) Lagre, kompiler og kjør koden. Som vist i diagrammet opprettes to objekter og to referansevariabler.

 Søppelsamlermekanisme

Trinn 3) Fjern kommenteringen av linje 20, 21 og 22. Lagre, kompiler og kjør koden.

Trinn 4) Som vist i diagrammet nedenfor, peker nå to referansevariabler til det samme objektet.

Søppelsamlermekanisme

Trinn 5) Fjern kommenteringen av linje 23 og 24. Lagre, kompiler og kjør koden.

Trinn 6) Som vist nedenfor blir s2 null, men s3 peker fortsatt på objektet, så objektet er ennå ikke kvalifisert for søppeltømming.

 Søppelsamlermekanisme

Trinn 7) Fjern kommenteringen av linje 25 og 26. Lagre, kompiler og kjør koden.

Trinn 8) På dette tidspunktet peker ingen referanser til objektet, så det blir kvalifisert for Garbage Collector. Garbage Collector fjerner det fra minnet, og det er ingen måte å hente det på.

 Lær Garbage Collector

Slik sletter du et objekt i Java?

Java tilbyr ikke en manuell slettingsoperator, så standardmetoden er å fjerne alle referanser til objektet slik at søppelsamleren kan gjenvinne det.

1) For å gjøre et objekt kvalifisert for søppeltømming, tilordne alle referansevariabler som peker til det til null.

2) Primitive typer er ikke objekter, så de kan ikke tildeles null. Lagringsplassen deres gjenvinnes automatisk når den omkringliggende Stack-rammen åpnes.

Hvordan slette et objekt i Java

Spørsmål og svar

Stakken lagrer metoderammer, lokale variabler og referanser i rekkefølgen «sist inn, først ut» per tråd. Heapen lagrer alle objekter som er opprettet med new og deles på tvers av tråder, og det er derfor Garbage Collector administrerer den.

Garbage Collector bruker referansekjeder fra GC-røtter, som aktive tråder og statiske felt. Ethvert objekt som ikke kan nås fra en rot, anses som utilgjengelig og blir kvalifisert for gjenoppretting i løpet av neste innsamlingssyklus.

Den unge generasjonen inneholder kortlivede objekter i Eden- og Survivor-områdene. Den gamle generasjonen inneholder objekter som overlever flere samlinger. Metaspace er et native-minneområde som lagrer klassemetadata og erstattet den eldre PermGen i Java 8.

G1 er standard og passer til de fleste arbeidsbelastninger på heaps på flere gigabyte. ZGC og Shenandoah sikter seg inn på pauser på under en millisekund på veldig store heaps og er gode valg for latensfølsomme tjenester som kjører på Java 17 eller nyere.

Sett alle referanser som peker til objektet til null, eller la referansene falle utenfor omfanget når Stack-rammene deres poppes. Når ingen live-referanse når objektet, gjenvinner Garbage Collector Heap-minnet.

Ja. AI-drevne justeringsverktøy analyserer GC-logger, allokeringsrater og pausehistogrammer for å anbefale heapstørrelser, samlerflagg og Young Generation-forhold. De forkorter tilbakekoblingssløyfen sammenlignet med manuell justering, spesielt på tvers av G1-, ZGC- og Shenandoah-arbeidsbelastninger.

AI-baserte observasjonsplattformer innhenter heapdumps og live-målinger, og grupperer deretter beholdte objektgrafer for å flagge mistenkelige klasser og referansekjeder. Dette avdekker lekkasjekandidater raskere enn manuell heapanalyse og hjelper team med å finne rotårsaken i produksjonen.

Oppsummer dette innlegget med: