Stack Memory och Heap Space i Java

1. Introduktion

För att köra ett program på ett optimalt sätt delar JVM minne i stack- och heapminne. När vi deklarerar nya variabler och objekt, anropar ny metod, deklarerar en sträng eller utför liknande operationer, anger JVM minne till dessa operationer från antingen Stack Memory eller Heap Space.

I denna handledning diskuterar vi dessa minnesmodeller. Vi tar in några viktiga skillnader mellan dem, hur de lagras i RAM, de funktioner de erbjuder och var de ska användas.

2. Stapla minne i Java

Stack Memory i Java används för statisk minnestilldelning och körning av en tråd. Den innehåller primitiva värden som är specifika för en metod och referenser till objekt som finns i en hög, hänvisade från metoden.

Åtkomst till detta minne sker i LIFO-ordning (Last-In-First-Out). Närhelst en ny metod anropas skapas ett nytt block ovanpå stacken som innehåller värden som är specifika för den metoden, som primitiva variabler och referenser till objekt.

När metoden är klar med körningen spolas motsvarande stackram, flödet går tillbaka till anropsmetoden och utrymme blir tillgängligt för nästa metod.

2.1. Viktiga funktioner i Stack Memory

Bortsett från vad vi har diskuterat hittills, är några andra funktioner i stackminnet:

  • Den växer och krymper när nya metoder anropas respektive returneras
  • Variabler i stacken finns bara så länge som metoden som skapade dem körs
  • Det allokeras automatiskt och omplaceras när metoden är klar
  • Om det här minnet är fullt, kastar Java java.lang.StackOverFlowError
  • Åtkomst till detta minne går snabbt jämfört med högminne
  • Detta minne är trådsäkert eftersom varje tråd fungerar i sin egen stack

3. Heap Space i Java

Heap space i Java används för dynamisk minnestilldelning för Java-objekt och JRE-klasser under körning . Nya objekt skapas alltid i massor och referenserna till dessa objekt lagras i stackminnet.

Dessa objekt har global åtkomst och kan nås var som helst i applikationen.

Denna minnesmodell delas vidare upp i mindre delar som kallas generationer, dessa är:

  1. Young Generation - det är här alla nya objekt tilldelas och åldras. En mindre sopuppsamling sker när detta fylls
  2. Gamla eller fasta generationen - här lagras föremål som länge har kvar. När objekt lagras i den unga generationen ställs en tröskel för objektets ålder in och när denna tröskel nås flyttas objektet till den gamla generationen
  3. Permanent generation - detta består av JVM-metadata för runtime-klasser och applikationsmetoder

Dessa olika delar diskuteras också i den här artikeln - Skillnaden mellan JVM, JRE och JDK.

Vi kan alltid manipulera storleken på högminnet enligt våra krav. För mer information, besök den här länkade Baeldung-artikeln.

3.1. Viktiga funktioner i Java Heap Memory

Bortsett från vad vi har diskuterat hittills, är några andra funktioner i högutrymme:

  • Den nås via komplexa minneshanteringstekniker som inkluderar Young Generation, Old eller Tenured Generation och Permanent Generation
  • Om heaputrymmet är fullt kastar Java java.lang.OutOfMemoryError
  • Tillgången till detta minne är relativt långsammare än stackminnet
  • Detta minne, till skillnad från stacken, omplaceras inte automatiskt. Det behöver Garbage Collector för att frigöra oanvända föremål för att bibehålla effektiviteten i minnesanvändningen
  • Till skillnad från stack är en hög inte trådsäker och måste skyddas genom att synkronisera koden korrekt

4. Exempel

Baserat på vad vi hittills har lärt oss, låt oss analysera en enkel Java-kod och låt oss bedöma hur minnet hanteras här:

class Person { int id; String name; public Person(int id, String name) { this.id = id; this.name = name; } } public class PersonBuilder { private static Person buildPerson(int id, String name) { return new Person(id, name); } public static void main(String[] args) { int id = 23; String name = "John"; Person person = null; person = buildPerson(id, name); } }

Låt oss analysera detta steg för steg:

  1. När du anger huvudmetoden () skapas ett utrymme i stackminnet för att lagra primitiver och referenser för denna metod
    • Det primitiva värdet för heltal id kommer att lagras direkt i stackminnet
    • Referensvariabeln person av typen Person kommer också att skapas i stackminnet som pekar på det faktiska objektet i högen
  2. Samtalet till den parametrerade konstruktorpersonen (int, String) från main () kommer att tilldela ytterligare minne ovanpå föregående stack. Detta kommer att lagra:
    • Den här objektreferensen för det anropande objektet i stackminnet
    • Det primitiva värdet id i stackminnet
    • Referensvariabel av String argument namn som kommer att peka till den faktiska strängen från sträng pool i stackminne
  3. Den huvudsakliga metoden är vidare att anropa buildPerson () statiska metoden, för vilket ytterligare tilldelning kommer att äga rum i stackminnet ovanpå den tidigare. Detta lagrar igen variabler på det sätt som beskrivs ovan.
  4. Men för det nya objektet personen av typen Person , alla instansvariabler kommer att lagras i högen minne.

Denna fördelning förklaras i detta diagram:

5. Sammanfattning

Innan vi avslutar den här artikeln, låt oss snabbt sammanfatta skillnaderna mellan Stack Memory och Heap Space:

Parameter Stackminne Heap Space
Ansökan Stack används i delar, en i taget under körning av en tråd Hela applikationen använder Heap space under körning
Storlek Stack har storleksbegränsningar beroende på operativsystem och är vanligtvis mindre än Heap Det finns ingen storleksbegränsning på Heap
Lagring Lagrar endast primitiva variabler och referenser till objekt som skapas i Heap Space Här lagras alla nyskapade objekt
Beställa Den nås med hjälp av LIFO-minnesallokeringssystemet Last-in First-out Detta minne nås via komplexa minneshanteringstekniker som inkluderar Young Generation, Old eller Tenured Generation och Permanent Generation.
Liv Stackminne finns bara så länge som den aktuella metoden körs Heap-utrymme finns så länge programmet körs
Effektivitet Jämfört mycket snabbare att fördela jämfört med hög Långsammare att fördela jämfört med stack
Allocation / Deallocation Detta minne tilldelas automatiskt och delas ut när en metod anropas respektive returneras Heap-utrymme tilldelas när nya objekt skapas och omlokaliseras av Gargabe Collector när de inte längre refereras till

6. Sammanfattning

Stack och heap är två sätt på vilka Java tilldelar minne. I den här artikeln förstod vi hur de fungerar och när vi ska använda dem för att utveckla bättre Java-program.

För att lära dig mer om Memory Management i Java, ta en titt på den här artikeln här. Vi diskuterade också JVM Garbage Collector som diskuteras kort i denna artikel.