Geheugenbeheer in Java

โšก Slimme samenvatting

Geheugenbeheer in Java legt uit hoe de JVM het runtimegeheugen verdeelt over Stack, Heap, CodeEn statische regio's, hoe objectreferenties stromen tijdens methodeaanroepen, en hoe de garbage collector onbereikbare objecten vrijmaakt, zodat applicaties stabiel blijven en vrij zijn van geheugenlekken.

  • ???? JVM-geheugenindeling: Java Het geheugen is opgesplitst in een heap voor objecten, een stack voor method frames en lokale variabelen, plus aparte gebieden voor bytecode en statische data.
  • ๐Ÿ“š Stack versus Heap: Stackframes volgen het Last-In-First-Out-principe en slaan primitieve gegevenstypen en referenties op, terwijl de heap alle objecten bevat die met de new-operator zijn aangemaakt.
  • โ™ป๏ธ Afvalinzameling: De vuilnisman tracks-bereikbaarheid via referentieketens en maakt automatisch geheugen vrij van objecten die door geen enkele thread kunnen worden bereikt.
  • โœ… Moderne verzamelaars: Productieworkloads zijn steeds vaker afhankelijk van G1, ZGC en Shenandoah voor het verzamelen van gegevens met minimale pauzes over heaps van meerdere gigabytes.
  • ๐Ÿงช Praktisch voorbeeld: Een stapsgewijze handleiding voor de Student-klasse laat zien wanneer referenties in aanmerking komen voor verwijdering en hoe het nullen van referenties het onderliggende object vrijgeeft.

Geheugenbeheer in Java

Wat is stackgeheugen? Java?

Stapelgeheugen in Java De stack is het gedeelte van het JVM-geheugen dat methodeframes, lokale variabelen en referentievariabelen voor elke thread opslaat. De stack wordt altijd benaderd volgens het Last-In-First-Out-principe, waardoor de laatst aangeroepen methode bovenaan staat en de lokale variabelen ervan samen met het frame op de stack worden geplaatst en verwijderd.

Elke draad in de Java De virtuele machine krijgt een eigen stack, waardoor methodeaanroepen geรฏsoleerd en thread-safe blijven. Lokale primitieve gegevenstypen zoals int, boolean en double bevinden zich direct binnen het frame, terwijl objectreferenties die op de stack zijn opgeslagen, verwijzen naar objecten die op de heap zijn toegewezen.

Wat is heapgeheugen in Java?

Heapgeheugen is het gedeelde JVM-gebied waarin alle Java Objecten en arrays worden aangemaakt met de `new`-operator, samen met alle referentievariabelen die bij die objecten horen als instantievelden. In tegenstelling tot de stack wordt de heap gedeeld door alle threads, waardoor toegang tot objecten vaak synchronisatie vereist.

De heap is het gebied dat door de garbage collector wordt beheerd. Moderne HotSpot JVM's verdelen de heap in een jonge generatie voor kortstondige objecten en een oude generatie voor langlevende objecten, waarbij klassemetadata wordt opgeslagen in een aparte native regio genaamd metaspace.

Geheugentoewijzing in Java

Geheugentoewijzing in Java Het toewijzen van geheugen is het proces waarbij de JVM virtuele geheugenregio's reserveert voor variabelen en instanties van klassen en structuren tijdens de uitvoering van een programma. Het geheugen wordt niet direct aan een object toegewezen bij de declaratie; er wordt alleen een referentie aangemaakt. De daadwerkelijke toewijzing van het object vindt plaats via de `new`-operator, waardoor elk object op de heap wordt opgeslagen.

De Java De geheugenallocatie is onderverdeeld in de volgende secties:

  1. Hoop
  2. Opstapelen
  3. Code
  4. Statisch

Deze indeling van het geheugen is noodzakelijk voor een effectief beheer van de runtime.

  • De Code Deze sectie bevat uw samengestelde gegevens. bytecode.
  • De Opstapelen sectiewinkels methoden, lokale variabelen en referentievariabelen.
  • De Hoop sectie bevat objecten en kunnen ook referentievariabelen bevatten die als instantievelden worden bewaard.
  • De Statisch sectie bevat statische gegevens en statische methoden gedeeld over alle instanties.

Verschil tussen lokale en instantievariabele

Inzicht in de locatie van elk type variabele in de JVM helpt bij het verklaren van het gedrag van de stack en de heap. instantie variabele wordt verklaard binnen een klasse, maar buiten elke methode.en het bevindt zich op de Heap als onderdeel van het object.

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

A lokale variabele wordt verklaard binnen een methode, inclusief methodeargumentenen bevindt zich op de stack binnen het actieve frame.

public void sum(int a){

int x = a + 3;

// a, x are local variables

}

Verschil tussen stapel en hoop

De stack en de heap lossen verschillende problemen op binnen de JVM. De stack biedt elke thread snelle, deterministische toewijzing voor kortstondige data die gekoppeld is aan de scope van een methode, terwijl de heap een gedeelde ruimte biedt voor lang bestaande objecten waarnaar elke thread kan verwijzen. De korte video hieronder vat het verschil samen voordat de uitleg volgt.

Klik hier als de video niet toegankelijk is

Om te zien hoe Stack en Heap samenwerken, neem een โ€‹โ€‹hoofdmethode die methode m1 aanroept.

public void m1{
int x = 20;
}

In de JVM-stack wordt een frame aangemaakt voor methode m1.

Java Stapel en hoop

De variabele x in m1 wordt ook aangemaakt in het frame voor m1 op de Stack, zoals weergegeven in de onderstaande afbeelding.

Java Stapel en hoop

Methode m1 roept vervolgens methode m2 aan. In de stack wordt een nieuw frame voor m2 aangemaakt bovenop het frame voor m1.

Java Stapel en hoop

Java Stapel en hoop

De lokale variabelen b en c worden ook binnen het frame voor m2 op de stack aangemaakt.

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

Vervolgens roept m2 methode m3 aan. Opnieuw wordt er een frame voor m3 bovenop de stack aangemaakt, zoals hieronder weergegeven.

Java Stapel en hoop

Java Stapel en hoop

Stel nu dat methode m3 een object aanmaakt voor de klasse Account, die twee instantievariabelen int p en int q.

class Account {
    int p;
    int q;
}

Hier is de code voor methode m3.

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

De instructie new Account() maakt een object van het type Account aan op de heap.

Java Stapel en hoop

De referentievariabele ref wordt op de stack aangemaakt binnen het frame voor m3.

Java Stapel en hoop

De toewijzingsoperator zorgt ervoor dat de referentievariabele naar het object op de heap wijst.

Java Stapel en hoop

Zodra de methode klaar is met uitvoeren, keert de controle terug naar de aanroepende methode, in dit geval methode m2.

Java Stapel en hoop

Het frame voor methode m3 wordt uit de stack verwijderd.

Java Stapel en hoop

Omdat de referentievariabele niet langer naar het object op de heap wijst, komt dat object in aanmerking voor garbage collection.

Java Stapel en hoop

Zodra methode m2 is voltooid, wordt deze van de stack verwijderd en worden alle bijbehorende variabelen ontoegankelijk. Hetzelfde gebeurt met methode m1, waarna de controle uiteindelijk terugkeert naar de hoofdmethode.

Wat als een object een andere referentie als instantievariabele bevat?

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

In dit geval bevindt de referentievariabele child zich op de heap als onderdeel van het object A en wijst deze op zijn beurt naar zijn eigen object B, zoals hieronder weergegeven.

Java Stapel en hoop

Waar zit afvalinzameling in? Java?

Afvalinzameling in Java Dit is het proces waarmee de JVM automatisch geheugenbeheer uitvoert. De garbage collector vindt objecten die niet langer bereikbaar zijn via actieve referenties en maakt hun geheugen vrij. Dynamische geheugenallocatie vindt plaats via de `new`-operator en het geheugen blijft toegewezen totdat het programma geen referenties meer naar het object heeft.

Wanneer er geen verwijzingen meer zijn, wordt het object als overbodig beschouwd en kan het geheugen dat het in beslag neemt, worden vrijgemaakt. Er is geen expliciete noodzaak om een โ€‹โ€‹object te vernietigen, omdat Java De garbage collector handelt de deallocatie automatisch af.

De techniek die hierachter schuilgaat, staat bekend als Garbage CollectionProgramma's die er niet in slagen geheugen vrij te geven, crashen uiteindelijk wanneer er niets meer te alloceren valt. Van dergelijke programma's wordt gezegd dat ze vastlopen. geheugenlekken. Afvalinzameling in Java wordt automatisch uitgevoerd Dit gebeurt gedurende de gehele looptijd van het programma, waardoor de last van handmatige deallocatie wordt weggenomen en het risico op datalekken wordt verkleind.

In C is de programmeur daarentegen verantwoordelijk voor het vrijgeven van dynamisch toegewezen geheugen via de free()-functie. Dit is waar Java Geheugenbeheer biedt een groot voordeel.

Moderne HotSpot JVM's bevatten verschillende garbage collectors die zijn afgestemd op verschillende workloads. De standaard G1 garbage collector streeft naar een evenwichtige doorvoer en pauzetijden op heaps van meerdere gigabytes. ZGC en Shenandoah streven naar pauzes van minder dan een milliseconde op zeer grote heaps, waardoor ze bijtracessentieel voor latencygevoelige services. Het kiezen van de juiste collector en het afstemmen van de Young Generation, Old Generation en Metaspace-groottes is een kernvaardigheid voor Java uitvoerend werk.

Let op: Alle objecten worden aangemaakt in het heap-gedeelte van het geheugen, het gebied dat door de garbage collector wordt beheerd.

Voorbeeld: Om het afvalverzamelaarmechanisme te leren Java

Deze handleiding laat zien wanneer verwijzingen in een eenvoudig programma in aanmerking komen voor garbage collection.

Stap 1) Kopieer de volgende code in een 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();
  }
}

Stap 2) Sla de code op, compileer deze en voer hem uit. Zoals in het diagram te zien is, worden er twee objecten en twee referentievariabelen aangemaakt.

 Afvalverzamelaarmechanisme

Stap 3) Verwijder de commentaartekens bij regel 20, 21 en 22. Sla de code op, compileer deze en voer hem uit.

Stap 4) Zoals in het onderstaande diagram te zien is, verwijzen twee referentievariabelen nu naar hetzelfde object.

Afvalverzamelaarmechanisme

Stap 5) Verwijder de commentaartekens bij regel 23 en 24. Sla de code op, compileer deze en voer hem uit.

Stap 6) Zoals hieronder weergegeven, wordt s2 null, maar s3 wijst nog steeds naar het object, waardoor het object nog niet in aanmerking komt voor garbage collection.

 Afvalverzamelaarmechanisme

Stap 7) Verwijder de commentaartekens bij regel 25 en 26. Sla de code op, compileer deze en voer hem uit.

Stap 8) Op dit punt verwijst geen enkele bron meer naar het object, waardoor het in aanmerking komt voor garbage collection. De garbage collector verwijdert het uit het geheugen en er is geen manier om het terug te halen.

 Leer vuilnisman

Hoe verwijder ik een object in Java?

Java Omdat er geen handmatige verwijderingsoperator beschikbaar is, is de standaardaanpak om elke verwijzing naar het object te verwijderen, zodat de garbage collector het kan vrijmaken.

1) Om een โ€‹โ€‹object geschikt te maken voor garbage collection, moet je elke referentievariabele die ernaar verwijst, de waarde null toewijzen.

2) Primitieve gegevenstypen zijn geen objecten, dus er kan geen null-waarde aan worden toegekend. Hun geheugen wordt automatisch vrijgegeven wanneer het omringende stackframe wordt verwijderd.

Hoe een object te verwijderen in Java

Veelgestelde vragen

De stack slaat methodeframes, lokale variabelen en referenties op in de volgorde Last-In-First-Out per thread. De heap slaat alle objecten op die met `new` zijn aangemaakt en wordt gedeeld tussen threads, vandaar dat de garbage collector deze beheert.

De garbage collector doorloopt referentieketens vanaf GC-roots, zoals actieve threads en statische velden. Elk object dat niet bereikbaar is vanuit een root, wordt als onbereikbaar beschouwd en komt in aanmerking voor vrijgave tijdens de volgende garbage collection-cyclus.

De Young Generation bewaart kortstondige objecten in Eden- en Survivor-ruimtes. De Old Generation bewaart objecten die meerdere collecties overleven. Metaspace is een geheugenregio die metadata van klassen opslaat en de oudere PermGen heeft vervangen. Java 8.

G1 is de standaard en is geschikt voor de meeste workloads op heaps van meerdere gigabytes. ZGC en Shenandoah streven naar pauzes van minder dan een milliseconde op zeer grote heaps en zijn goede keuzes voor latencygevoelige services die draaien op Java 17 of hoger.

Stel alle verwijzingen naar het object in op null, of laat de verwijzingen buiten het bereik vallen wanneer hun stackframes worden verwijderd. Zodra er geen actieve verwijzingen meer naar het object zijn, maakt de garbage collector het heapgeheugen vrij.

Ja. Door AI aangedreven tuningtools analyseren GC-logs, allocatiesnelheden en pauzehistogrammen om heapgroottes, collector-flags en Young Generation-ratio's aan te bevelen. Ze verkorten de feedbackloop in vergelijking met handmatige tuning, met name bij G1-, ZGC- en Shenandoah-workloads.

Op AI gebaseerde observatieplatforms verwerken heapdumps en live metrics, en clusteren vervolgens de bewaard gebleven objectgrafieken om verdachte klassen en referentieketens te signaleren. Dit brengt potentiรซle geheugenlekken sneller aan het licht dan handmatige heapanalyse en helpt teams de hoofdoorzaak in productie te achterhalen.

Vat dit bericht samen met: