Minneshantering i Java

⚡ Smart sammanfattning

Minneshantering i Java förklarar hur JVM:n delar upp runtime-minnet i Stack, Heap, Code, och statiska regioner, hur objektreferenser flödar under metodanrop, och hur Garbage Collector återtar oåtkomliga objekt så att applikationer förblir stabila och fria från minnesläckor.

  • 🧠 JVM-minneslayout: Java minnet är uppdelat i Heap för objekt, Stack för metodramar och lokala variabler, plus dedikerade områden för bytekod och statisk data.
  • 📚 Stack vs. Heap: Stackramar följer ordningen sist in, först ut och lagrar primitiver och referenser, medan heapen innehåller alla objekt som skapats med den nya operatorn.
  • ♻️ Skräp samling: Sopsamlaren tracks nåbarhet genom referenskedjor och återkräver automatiskt minne från objekt som ingen tråd kan nå.
  • Moderna samlare: Produktionsarbetsbelastningar förlitar sig i allt högre grad på G1, ZGC och Shenandoah för insamling med låg paus över heaps på flera gigabyte.
  • 🧪 Praktiskt exempel: En steg-för-steg-genomgång av Student-klassen visar när referenser blir berättigade till insamling och hur nollställning av referenser frigör det underliggande objektet.

Minneshantering i Java

Vad är stackminne i Java?

Stackminne i Java är den region i JVM-minnet som lagrar metodframes, lokala variabler och referensvariabler för varje tråd. Stacken nås alltid i ordningen sist in, först ut, så den senast anropade metoden placeras överst, och dess lokala variabler skickas och poppas med framen.

Varje tråd i Java Virtuell maskin får sin egen Stack, vilket håller metodanrop isolerade och trådsäkra enligt designen. Primitiva lokala värden som int, boolean och double finns direkt inuti framen, medan objektreferenser lagrade på Stack pekar på objekt allokerade på Heap.

Vad är Heap Memory i Java?

Heapminne är den delade JVM-regionen som innehåller alla Java objekt och array som skapats med den nya operatorn, tillsammans med eventuella referensvariabler som tillhör dessa objekt som instansfält. Till skillnad från Stack delas Heap mellan alla trådar, vilket är anledningen till att objektåtkomst ofta kräver synkronisering.

Heapen är det område som Garbage Collector hanterar. Moderna HotSpot JVM:er delar upp Heapen i en Young Generation för kortlivade objekt och en Old Generation för långlivade objekt, med klassmetadata lagrade i en separat nativ region som kallas Metaspace.

Minnestilldelning in Java

Minnestilldelning in Java är den process genom vilken JVM avsätter virtuella minnesområden för variabler och instanser av klasser och strukturer under programkörning. Minnet allokeras inte till ett objekt vid deklaration; endast en referens skapas. Den faktiska objektallokeringen sker via new-operatorn, så varje objekt finns på heapen.

Ocuco-landskapet Java Minnesallokeringen är indelad i följande avsnitt:

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

Denna minnesdelning krävs för effektiv hantering av körtiden.

  • Ocuco-landskapet Code avsnittet innehåller din sammanställda bytekod.
  • Ocuco-landskapet Stack sektionsbutiker metoder, lokala variabler och referensvariabler.
  • Ocuco-landskapet heap avsnitt innehåller objekt och kan även innehålla referensvariabler som hålls som instansfält.
  • Ocuco-landskapet Statisk sektionshållplatser statiska data och statiska metoder delas över alla instanser.

Skillnad mellan lokal och instansvariabel

Att förstå var varje typ av variabel finns i JVM:n hjälper till att förklara Stack- och Heap-beteendet. instansvariabel förklaras inuti en klass men utanför vilken metod som helst, och den bor på Högen som en del av sitt objekt.

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

A lokal variabel förklaras inuti en metod, inklusive metodargument, och finns på stacken inuti den aktiva ramen.

public void sum(int a){

int x = a + 3;

// a, x are local variables

}

Skillnaden mellan Stack och Heap

Stacken och Heapen löser olika problem inuti JVM:n. Stacken ger varje tråd snabb, deterministisk allokering för kortlivade data kopplade till metodens omfattning, medan Heapen tillhandahåller en delad region för långlivade objekt som vilken tråd som helst kan referera till. Den korta videon nedan sammanfattar kontrasten innan genomgången som följer.

Klicka här. om videon inte är tillgänglig

För att se hur Stack och Heap samarbetar, betrakta en huvudmetod som anropar metod m1.

public void m1{
int x = 20;
}

I JVM-stacken skapas en ram för metod m1.

Java Stack och heap

Variabeln x i m1 skapas också i ramen för m1 på stacken, som visas i bilden nedan.

Java Stack och heap

Metod m1 anropar sedan metod m2. I stacken skapas en ny ram för m2 ovanpå ramen för m1.

Java Stack och heap

Java Stack och heap

De lokala variablerna b och c skapas också inuti ramen för m2 på stacken.

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

Därefter anropar m2 metoden m3. Återigen skapas en ram för m3 högst upp i stacken, som visas nedan.

Java Stack och heap

Java Stack och heap

Säg nu att metod m3 skapar ett objekt för klassen Account, vilket har två instansvariabler int p och int q.

class Account {
    int p;
    int q;
}

Här är koden för metod m3.

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

Satsen new Account() skapar ett objekt av typen Account på Heapen.

Java Stack och heap

Referensvariabeln ref skapas på stacken inuti ramen för m3.

Java Stack och heap

Tilldelningsoperatorn får referensvariabeln att peka på objektet på heapen.

Java Stack och heap

När metoden har körts återgår kontrollen till den anropande metoden, som i det här fallet är metod m2.

Java Stack och heap

Ramen för metod m3 spolas ut ur stacken.

Java Stack och heap

Eftersom referensvariabeln inte längre pekar på objektet på heapen blir det objektet berättigat till skräpinsamling.

Java Stack och heap

När metod m2 är klar tas den bort från stacken och alla dess variabler blir otillgängliga. Detsamma händer för metod m1, och så småningom återgår kontrollen till huvudmetoden.

Vad händer om ett objekt har en annan referens 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 det här fallet finns referensvariabeln barn på Heap som en del av A-objektet, och pekar i sin tur till sitt eget B-objekt, som visas nedan.

Java Stack och heap

Vad finns Garbage Collection i Java?

Sophämtning in Java är den process genom vilken JVM utför minneshantering automatiskt. Garbage Collector hittar objekt som inte längre är nåbara från någon live-referens och återtar deras minne. Dynamisk minnesallokering sker via den nya operatorn, och minnet förblir allokerat tills programmet inte längre har någon referens till objektet.

När inga referenser finns kvar anses objektet inte längre behövas, och det minne det upptar kan återvinnas. Det finns inget uttryckligt behov av att förstöra ett objekt eftersom Java hanterar avallokeringen automatiskt via Garbage Collector.

Tekniken bakom detta är känd som Skräp samlingProgram som inte frigör minne kraschar så småningom när det inte finns något kvar att allokera. Sådana program sägs ha minne läcker. Sophämtning in Java körs automatiskt under programmets livslängd, vilket eliminerar bördan av manuell deallokering och minskar risken för läckor.

I C, däremot, är programmeraren ansvarig för att frigöra minne som allokeras dynamiskt via funktionen free(). Det är här Java minneshantering erbjuder en stark fördel.

Moderna HotSpot JVM:er levererar flera Garbage Collectors som är anpassade för olika arbetsbelastningar. Standard G1 Garbage Collector siktar på balanserad dataflödes- och paustider på heaps med flera gigabyte. ZGC och Shenandoah siktar på pauser på under en millisekund på mycket stora heaps, vilket gör dem vidtraceffektiv för latenskänsliga tjänster. Att välja rätt samlare och finjustera storlekarna för den unga generationen, den gamla generationen och metaspace är en kärnkompetens för Java prestationsarbete.

Obs: Alla objekt skapas i Heap-sektionen av minnet, vilket är den region som Garbage Collector hanterar.

Exempel: Att lära sig garbage Collector Mechanism i Java

Den här genomgången visar när referenser blir berättigade till sophämtning i ett enkelt program.

Steg 1) Kopiera följande kod till 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();
  }
}

Steg 2) Spara, kompilera och kör koden. Som visas i diagrammet skapas två objekt och två referensvariabler.

 Garbage Collector Mekanism

Steg 3) Avkommentera raderna 20, 21 och 22. Spara, kompilera och kör koden.

Steg 4) Som visas i diagrammet nedan pekar nu två referensvariabler på samma objekt.

Garbage Collector Mekanism

Steg 5) Avkommentera raderna 23 och 24. Spara, kompilera och kör koden.

Steg 6) Som visas nedan blir s2 null, men s3 pekar fortfarande på objektet, så objektet är ännu inte kvalificerat för sophämtning.

 Garbage Collector Mekanism

Steg 7) Avkommentera raderna 25 och 26. Spara, kompilera och kör koden.

Steg 8) Vid det här laget pekar inga referenser på objektet, så det blir kvalificerat för Garbage Collector. Garbage Collector tar bort det från minnet, och det finns inget sätt att hämta det.

 Lär dig Garbage Collector

Hur man tar bort ett objekt i Java?

Java tillhandahåller ingen manuell borttagningsoperator, så standardmetoden är att ta bort alla referenser till objektet så att Garbage Collector kan återta det.

1) För att göra ett objekt lämpligt för Garbage Collection, tilldela varje referensvariabel som pekar på det till null.

2) Primitiva typer är inte objekt, så de kan inte tilldelas null. Deras lagringsutrymme återvinns automatiskt när den omgivande Stack-ramen poppas upp.

Hur man tar bort ett objekt i Java

Vanliga frågor

Stacken lagrar metodramar, lokala variabler och referenser i ordningen sist in, först ut per tråd. Heapen lagrar alla objekt som skapats med new och delas mellan trådar, vilket är anledningen till att Garbage Collector hanterar den.

Garbage Collector använder referenskedjor från GC-rötter, såsom aktiva trådar och statiska fält. Alla objekt som inte kan nås från en rot anses vara oåtkomliga och blir berättigade till återställning under nästa insamlingscykel.

Den unga generationen innehåller kortlivade objekt i Eden- och Survivor-utrymmena. Den gamla generationen innehåller objekt som överlever flera samlingar. Metaspace är en region i det ursprungliga minnet som lagrar klassmetadata och ersatte den äldre PermGen i Java 8.

G1 är standardinställningen och passar de flesta arbetsbelastningar på heaps med flera gigabyte. ZGC och Shenandoah riktar in sig på pauser på under en millisekund på mycket stora heaps och är bra val för latenskänsliga tjänster som körs på Java 17 eller senare.

Sätt varje referens som pekar på objektet till null, eller låt referenserna falla utanför räckvidden när deras Stack-ramar öppnas. När ingen Live-referens når objektet återtar Garbage Collector dess Heap-minne.

Ja. AI-drivna finjusteringsverktyg analyserar GC-loggar, allokeringshastigheter och paushistogram för att rekommendera heapstorlekar, samlarflaggor och Young Generation-förhållanden. De förkortar återkopplingsslingan jämfört med manuell finjustering, särskilt över G1-, ZGC- och Shenandoah-arbetsbelastningar.

AI-baserade observationsplattformar matar in heapdumps och live-mätvärden, och klustrar sedan kvarhållna objektgrafer för att flagga misstänkta klasser och referenskedjor. Detta avslöjar läckkandidater snabbare än manuell heapanalys och hjälper team att lokalisera grundorsaken i produktionen.

Sammanfatta detta inlägg med: