Stack Memory en Heap Space in Java

1. Inleiding

Om een ​​applicatie op een optimale manier uit te voeren, verdeelt JVM het geheugen in stack- en heap-geheugen. Telkens wanneer we nieuwe variabelen en objecten declareren, roep een nieuwe methode aan, declareer een Draad of soortgelijke bewerkingen uitvoeren, wijst JVM geheugen aan deze bewerkingen toe vanuit Stack Memory of Heap Space.

In deze tutorial bespreken we deze geheugenmodellen. We zullen enkele belangrijke verschillen tussen hen noemen, hoe ze in RAM worden opgeslagen, de functies die ze bieden en waar ze kunnen worden gebruikt.

2. Stapel geheugen in Java

Stack Memory in Java wordt gebruikt voor statische geheugentoewijzing en het uitvoeren van een thread. Het bevat primitieve waarden die specifiek zijn voor een methode en verwijzingen naar objecten die zich in een heap bevinden, verwezen vanuit de methode.

Toegang tot dit geheugen is in de volgorde Last-In-First-Out (LIFO). Telkens wanneer een nieuwe methode wordt aangeroepen, wordt een nieuw blok bovenop de stapel gemaakt dat waarden bevat die specifiek zijn voor die methode, zoals primitieve variabelen en verwijzingen naar objecten.

Wanneer de uitvoering van de methode is voltooid, wordt het bijbehorende stapelframe leeggemaakt, gaat de stroom terug naar de aanroepende methode en komt er ruimte beschikbaar voor de volgende methode.

2.1. Belangrijkste kenmerken van Stack Memory

Afgezien van wat we tot nu toe hebben besproken, volgen hier enkele andere kenmerken van stapelgeheugen:

  • Het groeit en krimpt naarmate nieuwe methoden respectievelijk worden aangeroepen en geretourneerd
  • Variabelen in de stapel bestaan ​​alleen zolang de methode waarmee ze zijn gemaakt, actief is
  • Het wordt automatisch toegewezen en ongedaan gemaakt wanneer de methode de uitvoering heeft voltooid
  • Als dit geheugen vol is, gooit Java java.lang.StackOverFlowError
  • Toegang tot dit geheugen is snel in vergelijking met heap-geheugen
  • Dit geheugen is threadsafe omdat elke thread in zijn eigen stapel werkt

3. Heap Space in Java

Heapruimte in Java wordt gebruikt voor dynamische geheugentoewijzing voor Java-objecten en JRE-klassen tijdens runtime. Nieuwe objecten worden altijd in heapruimte gemaakt en de verwijzingen naar deze objecten worden in het stapelgeheugen opgeslagen.

Deze objecten hebben globale toegang en zijn overal in de applicatie toegankelijk.

Dit geheugenmodel is verder onderverdeeld in kleinere delen die generaties worden genoemd, dit zijn:

  1. Jonge generatie - hier worden alle nieuwe objecten toegewezen en verouderd. Een kleine Garbage collection vindt plaats wanneer deze vol raakt
  2. Oude of vaste generatie - dit is waar lang overgebleven objecten worden opgeslagen. Wanneer objecten worden opgeslagen in de Young Generation, wordt een drempel voor de leeftijd van het object ingesteld en wanneer die drempel wordt bereikt, wordt het object verplaatst naar de oude generatie
  3. Permanente generatie - dit bestaat uit JVM-metadata voor de runtime-klassen en toepassingsmethoden

Deze verschillende delen worden ook besproken in dit artikel - Verschil tussen JVM, JRE en JDK.

We kunnen altijd de grootte van het heap-geheugen manipuleren volgens onze vereisten. Bezoek dit gelinkte Baeldung-artikel voor meer informatie.

3.1. Belangrijkste kenmerken van Java Heap Memory

Afgezien van wat we tot nu toe hebben besproken, volgen hier enkele andere kenmerken van heapspace:

  • Het is toegankelijk via complexe geheugenbeheertechnieken, waaronder Young Generation, Old of Tenured Generation en Permanent Generation
  • Als de heapruimte vol is, gooit Java java.lang.OutOfMemoryError
  • Toegang tot dit geheugen is relatief langzamer dan stapelgeheugen
  • Dit geheugen wordt, in tegenstelling tot stack, niet automatisch ongedaan gemaakt. Het heeft Garbage Collector nodig om ongebruikte objecten vrij te maken om de efficiëntie van het geheugengebruik te behouden
  • In tegenstelling tot stack is een heap niet threadsafe en moet deze worden bewaakt door de code correct te synchroniseren

4. Voorbeeld

Laten we, op basis van wat we tot nu toe hebben geleerd, een eenvoudige Java-code analyseren en beoordelen hoe het geheugen hier wordt beheerd:

klasse Persoon {int id; String naam; publieke persoon (int id, String naam) {this.id = id; this.name = naam; }} openbare klasse PersonBuilder {privé statische Persoon buildPerson (int id, String naam) {retourneer nieuwe Persoon (id, naam); } public static void main (String [] args) {int id = 23; String name = "John"; Persoon person = null; person = buildPerson (id, naam); }}

Laten we deze stap voor stap analyseren:

  1. Bij het betreden van het hoofd() methode, zou een ruimte in het stapelgeheugen worden gemaakt om primitieven en referenties van deze methode op te slaan
    • De primitieve waarde van integer ID kaart wordt direct in het stapelgeheugen opgeslagen
    • De referentievariabele persoon van het type Persoon wordt ook gemaakt in het stapelgeheugen dat naar het daadwerkelijke object in de heap verwijst
  2. De aanroep van de geparameteriseerde constructor Persoon (int, String) van hoofd() zal meer geheugen toewijzen bovenop de vorige stapel. Dit slaat op:
    • De dit objectreferentie van het aanroepende object in het stapelgeheugen
    • De primitieve waarde ID kaart in het stapelgeheugen
    • De referentievariabele van Draad argument naam die zal verwijzen naar de daadwerkelijke string uit de string-pool in het heap-geheugen
  3. De hoofd methode roept verder de buildPerson () statische methode, waarvoor verdere toewijzing zal plaatsvinden in het stapelgeheugen bovenop de vorige. Dit zal weer variabelen opslaan op de hierboven beschreven manier.
  4. Voor het nieuw gemaakte object persoon van het type Persoon, worden alle instantievariabelen opgeslagen in het heap-geheugen.

Deze toewijzing wordt uitgelegd in dit diagram:

5. Samenvatting

Laten we, voordat we dit artikel afronden, kort de verschillen tussen het stapelgeheugen en de heapruimte samenvatten:

ParameterStapel geheugenHoop ruimte
ToepassingStack wordt in delen gebruikt, één voor één tijdens het uitvoeren van een threadDe hele applicatie gebruikt Heap-ruimte tijdens runtime
GrootteStack heeft limieten voor de grootte, afhankelijk van het besturingssysteem en is meestal kleiner dan HeapEr is geen maximale grootte op Heap
OpslagSlaat alleen primitieve variabelen en verwijzingen op naar objecten die in Heap Space zijn gemaaktAlle nieuw gemaakte objecten worden hier opgeslagen
BestellenHet is toegankelijk via het Last-in First-out (LIFO) geheugentoewijzingssysteemDit geheugen is toegankelijk via complexe geheugenbeheertechnieken, waaronder Young Generation, Old of Tenured Generation en Permanent Generation.
LevenHet stapelgeheugen bestaat alleen zolang de huidige methode actief isHeapruimte bestaat zolang de toepassing wordt uitgevoerd
EfficiëntieRelatief veel sneller toe te wijzen in vergelijking met heapLangzamer toe te wijzen in vergelijking met stapel
Toewijzing / vrijgaveDit geheugen wordt automatisch toegewezen en ongedaan gemaakt wanneer een methode respectievelijk wordt aangeroepen en geretourneerdHeapruimte wordt toegewezen wanneer nieuwe objecten worden gemaakt en de toewijzing wordt opgeheven door Gargabe Collector wanneer er niet langer naar wordt verwezen

6. Conclusie

Stack en heap zijn twee manieren waarop Java geheugen toewijst. In dit artikel hebben we begrepen hoe ze werken en wanneer we ze moeten gebruiken om betere Java-programma's te ontwikkelen.

Lees dit artikel hier voor meer informatie over geheugenbeheer in Java. We hebben ook de JVM Garbage Collector besproken, die in dit artikel kort wordt besproken.


$config[zx-auto] not found$config[zx-overlay] not found