Hukommelseshåndtering i Java

⚡ Smart opsummering

Hukommelseshåndtering i Java forklarer, hvordan JVM'en opdeler runtime-hukommelse på tværs af Stack, Heap, Code, og statiske regioner, hvordan objektreferencer flyder under metodekald, og hvordan Garbage Collector genvinder uopnåelige objekter, så applikationer forbliver stabile og fri for hukommelseslækager.

  • 🧠 JVM-hukommelseslayout: Java Hukommelsen er opdelt i Heap til objekter, Stack til metoderammer og lokale variabler, plus dedikerede områder til bytecode og statiske data.
  • 📚 Stak vs. bunke: Stakrammer følger rækkefølgen "sidst ind, først ud" og gemmer primitiver og referencer, mens heap'en indeholder alle objekter, der er oprettet med den nye operator.
  • ♻️ Dagrenovation: Skraldesamleren tracks tilgængelighed via referencekæder og genvinder automatisk hukommelse fra objekter, som ingen tråd kan nå.
  • Moderne samlere: Produktionsarbejdsbelastninger er i stigende grad afhængige af G1, ZGC og Shenandoah til indsamling med lav pause på tværs af heaps på flere gigabyte.
  • 🧪 Praktisk eksempel: En trinvis gennemgang af Student-klassen viser, hvornår referencer bliver berettigede til indsamling, og hvordan nulstilling af referencer frigiver det underliggende objekt.

Hukommelseshåndtering i Java

Hvad er stakhukommelse i Java?

Stak hukommelse i Java er det område af JVM-hukommelsen, der lagrer metoderammer, lokale variabler og referencevariabler for hver tråd. Stakken tilgås altid i rækkefølgen "Sidst ind, Først ud", så den senest kaldede metode sidder øverst, og dens lokale variabler pushes og poppes sammen med rammen.

Hver tråd i Java Den virtuelle maskine modtager sin egen stak, som isolerer og trådsikrer metodekald per design. Primitive lokale værdier som int, boolean og double findes direkte inde i rammen, mens objektreferencer gemt på stakken peger på objekter allokeret på heapen.

Hvad er Heap Memory i Java?

Heaphukommelse er den delte JVM-region, der indeholder alle Java objekt og array oprettet med den nye operator, sammen med eventuelle referencevariabler, der tilhører disse objekter som instansfelter. I modsætning til Stack deles Heap på tværs af alle tråde, hvilket er grunden til, at objektadgang ofte kræver synkronisering.

Heapen er det område, som Garbage Collector administrerer. Moderne HotSpot JVM'er opdeler Heapen i en Young Generation for kortlivede objekter og en Old Generation for langlivede objekter, hvor klassemetadata gemmes i en separat, oprindelig region kaldet Metaspace.

Hukommelsestildeling ind Java

Hukommelsestildeling ind Java er den proces, hvorved JVM'en afsætter virtuelle hukommelsesområder til variabler og instanser af klasser og strukturer under programudførelse. Hukommelsen allokeres ikke til et objekt ved deklaration; kun en reference oprettes. Den faktiske objektallokering sker via new-operatoren, så hvert objekt findes på heapen.

Java Hukommelsesallokering er opdelt i følgende sektioner:

  1. bunke
  2. Stak
  3. Code
  4. statisk

Denne opdeling af hukommelse er nødvendig for effektiv styring af runtime.

  • Code afsnittet indeholder dine kompilerede bytekode.
  • Stak sektionsbutikker metoder, lokale variabler og referencevariabler.
  • bunke afsnit indeholder objekter og kan også indeholde referencevariabler, der holdes som instansfelter.
  • statisk sektionshold statiske data og statiske metoder delt på tværs af alle instanser.

Forskellen mellem lokal og instansvariabel

At forstå, hvor hver type variabel befinder sig i JVM'en, hjælper med at forklare Stack- og Heap-adfærd. instansvariabel erklæres inden for en klasse, men uden for enhver metode, og den lever på Høngen som en del af dens objekt.

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

A lokal variabel erklæres inde i en metode, inklusive metodeargumenter, og ligger på stakken inde i den aktive ramme.

public void sum(int a){

int x = a + 3;

// a, x are local variables

}

Forskellen mellem stak og heap

Stack og Heap løser forskellige problemer i JVM'en. Stack giver hver tråd hurtig, deterministisk allokering af kortlivede data knyttet til metodeomfang, mens Heap giver et delt område for langlivede objekter, som enhver tråd kan referere til. Den korte video nedenfor opsummerer kontrasten før den følgende gennemgang.

Klik link. hvis videoen ikke er tilgængelig

For at se, hvordan Stack og Heap samarbejder, kan man betragte en hovedmetode, der kalder metode m1.

public void m1{
int x = 20;
}

I JVM-stakken oprettes en frame til metode m1.

Java Stack og Heap

Variablen x i m1 oprettes også i rammen for m1 på stakken, som vist på billedet nedenfor.

Java Stack og Heap

Metode m1 kalder derefter metode m2. I stakken oprettes en ny ramme for m2 oven på rammen for m1.

Java Stack og Heap

Java Stack og Heap

De lokale variabler b og c oprettes også inde i rammen for m2 på stakken.

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

Dernæst kalder m2 metoden m3. Igen oprettes en frame til m3 øverst i stakken, som vist nedenfor.

Java Stack og Heap

Java Stack og Heap

Lad os nu sige, at metode m3 opretter et objekt for klassen Account, som har to instansvariabler int p og int q.

class Account {
    int p;
    int q;
}

Her er koden til metode m3.

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

Udtrykket new Account() opretter et objekt af typen Account på heapen.

Java Stack og Heap

Referencevariablen ref oprettes på stakken inde i rammen for m3.

Java Stack og Heap

Tildelingsoperatoren får referencevariablen til at pege på objektet på heapen.

Java Stack og Heap

Når metoden er udført, vender kontrollen tilbage til den kaldende metode, som i dette tilfælde er metode m2.

Java Stack og Heap

Rammen for metode m3 skylles ud af stakken.

Java Stack og Heap

Da referencevariablen ikke længere peger på objektet på heapen, bliver dette objekt berettiget til garbage collection.

Java Stack og Heap

Når metode m2 er færdig, fjernes den fra stakken, og alle dens variabler bliver utilgængelige. Det samme sker for metode m1, og til sidst vender kontrollen tilbage til hovedmetoden.

Hvad hvis et objekt har en anden reference 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 tilfælde findes referencevariablen "child" på Heap som en del af A-objektet og peger til gengæld på sit eget B-objekt, som vist nedenfor.

Java Stack og Heap

Hvad er Garbage Collection i Java?

Affaldsopsamling i Java er den proces, hvorved JVM'en automatisk udfører hukommelsesstyring. Garbage Collector finder objekter, der ikke længere kan nås fra nogen live-reference, og generobrer deres hukommelse. Dynamisk hukommelsesallokering sker via den nye operator, og hukommelsen forbliver allokeret, indtil programmet ikke længere har nogen reference til objektet.

Når der ikke længere er nogen referencer tilbage, anses objektet for ikke længere nødvendigt, og den hukommelse, det optager, kan genvindes. Der er ikke noget eksplicit behov for at ødelægge et objekt, fordi Java håndterer deallokeringen automatisk via Garbage Collector.

Teknikken bag dette er kendt som DagrenovationProgrammer, der ikke frigiver hukommelse, går ned, når der ikke er noget tilbage at allokere. Sådanne programmer siges at have hukommelse lækker. Affaldsopsamling i Java kører automatisk i hele programmets levetid, hvilket fjerner byrden ved manuel deallokering og reducerer risikoen for lækager.

I C er programmøren derimod ansvarlig for at frigive hukommelse allokeret dynamisk via free()-funktionen. Det er her Java Hukommelsesstyring tilbyder en stor fordel.

Moderne HotSpot JVM'er leveres med adskillige Garbage Collectors, der er indstillet til forskellige arbejdsbelastninger. Standard G1 Garbage Collector sigter mod balanceret gennemløbshastighed og pausetider på heaps på flere gigabyte. ZGC og Shenandoah sigter mod pauser på under et millisekund på meget store heaps, hvilket gør dem påtractiv til latenstidsfølsomme tjenester. At vælge den rigtige samler og justere størrelserne for den unge generation, den gamle generation og metaspace er en kernefærdighed for Java performancearbejde.

Bemærk: Alle objekter oprettes i Heap-sektionen af ​​hukommelsen, som er den region, som Garbage Collector administrerer.

Eksempel: At lære affaldsopsamlermekanisme i Java

Denne gennemgang viser, hvornår referencer bliver berettigede til Garbage Collection i et simpelt program.

Trin 1) Kopier følgende kode ind 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();
  }
}

Trin 2) Gem, kompiler og kør koden. Som vist i diagrammet oprettes to objekter og to referencevariabler.

 Garbage Collector Mekanisme

Trin 3) Fjern kommentaren fra linje 20, 21 og 22. Gem, kompiler og kør koden.

Trin 4) Som vist i diagrammet nedenfor peger to referencevariabler nu på det samme objekt.

Garbage Collector Mekanisme

Trin 5) Fjern kommentaren fra linje 23 og 24. Gem, kompiler og kør koden.

Trin 6) Som vist nedenfor bliver s2 null, men s3 peger stadig på objektet, så objektet er endnu ikke berettiget til Garbage Collection.

 Garbage Collector Mekanisme

Trin 7) Fjern kommentaren fra linje 25 og 26. Gem, kompiler og kør koden.

Trin 8) På dette tidspunkt peger ingen referencer på objektet, så det bliver berettiget til Garbage Collection. Garbage Collector fjerner det fra hukommelsen, og der er ingen måde at hente det på.

 Lær Garbage Collector

Sådan sletter du et objekt i Java?

Java tilbyder ikke en manuel sletteoperator, så standardmetoden er at fjerne alle referencer til objektet, så Garbage Collector kan genvinde det.

1) For at gøre et objekt berettiget til Garbage Collection, skal du tildele alle referencevariabler, der peger på det, til null.

2) Primitive typer er ikke objekter, så de kan ikke tildeles null. Deres lagerplads genvindes automatisk, når den omgivende Stack-ramme poppes.

Sådan sletter du et objekt i Java

Ofte Stillede Spørgsmål

Stakken gemmer metoderammer, lokale variabler og referencer i rækkefølgen "Last-In-First-Out" pr. tråd. Heapen gemmer alle objekter, der er oprettet med "new", og deles på tværs af tråde, hvilket er grunden til, at Garbage Collector administrerer den.

Garbage Collector bruger referencekæder fra GC-rødder, såsom aktive tråde og statiske felter. Ethvert objekt, der ikke kan nås fra en rod, betragtes som utilgængeligt og bliver berettiget til gendannelse under den næste indsamlingscyklus.

Den unge generation indeholder kortlivede objekter i Eden- og Survivor-rummene. Den gamle generation indeholder objekter, der overlever flere samlinger. Metaspace er et native-hukommelsesområde, der lagrer klassemetadata og erstattede den ældre PermGen i Java 8.

G1 er standardindstillingen og passer til de fleste arbejdsbelastninger på heaps på flere gigabyte. ZGC og Shenandoah sigter mod pauser på under en millisekund på meget store heaps og er gode valg til latenstidsfølsomme tjenester, der kører på Java 17 eller nyere.

Sæt alle referencer, der peger på objektet, til null, eller lad referencerne falde uden for rækkevidde, når deres Stack-rammer poppes. Når ingen live-reference når objektet, generobrer Garbage Collector sin Heap-hukommelse.

Ja. AI-drevne tuningværktøjer analyserer GC-logfiler, allokeringsrater og pausehistogrammer for at anbefale heapstørrelser, collector-flag og Young Generation-forhold. De forkorter feedback-loopet sammenlignet med manuel tuning, især på tværs af G1-, ZGC- og Shenandoah-arbejdsbelastninger.

AI-baserede observationsplatforme indtager heap dumps og live metrics og grupperer derefter bevarede objektgrafer for at markere mistænkelige klasser og referencekæder. Dette afslører lækagekandidater hurtigere end manuel heap-analyse og hjælper teams med at identificere den grundlæggende årsag i produktionen.

Opsummer dette indlæg med: