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.

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:
- Hoop
- Opstapelen
- Code
- 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.
De variabele x in m1 wordt ook aangemaakt in het frame voor m1 op de Stack, zoals weergegeven in de onderstaande afbeelding.
Methode m1 roept vervolgens methode m2 aan. In de stack wordt een nieuw frame voor m2 aangemaakt bovenop het frame voor m1.
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.
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.
De referentievariabele ref wordt op de stack aangemaakt binnen het frame voor m3.
De toewijzingsoperator zorgt ervoor dat de referentievariabele naar het object op de heap wijst.
Zodra de methode klaar is met uitvoeren, keert de controle terug naar de aanroepende methode, in dit geval methode m2.
Het frame voor methode m3 wordt uit de stack verwijderd.
Omdat de referentievariabele niet langer naar het object op de heap wijst, komt dat object in aanmerking voor garbage collection.
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.
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.
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.
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.
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.
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.


















