Java >> Java tutorial >  >> Tag >> Stack

Stack Memory og Heap Space i Java

1. Introduktion

For at køre en applikation på en optimal måde opdeler JVM hukommelsen i stack- og heap-hukommelse. Når vi erklærer nye variabler og objekter, kalder du en ny metode, erklærer en streng, eller udføre lignende operationer, udpeger JVM hukommelse til disse operationer fra enten Stack Memory eller Heap Space.

I denne tutorial vil vi undersøge disse hukommelsesmodeller. Først vil vi udforske deres nøglefunktioner. Så lærer vi, hvordan de gemmes i RAM, og hvor de skal bruges. Til sidst vil vi diskutere de vigtigste forskelle mellem dem.

2. Stack Memory i Java

Stack Memory i Java bruges til statisk hukommelsesallokering og udførelse af en tråd. Den indeholder primitive værdier, der er specifikke for en metode og referencer til objekter, der henvises til fra metoden, som er i en bunke.

Adgang til denne hukommelse er i Last-In-First-Out (LIFO) rækkefølge. Hver gang vi kalder en ny metode, oprettes en ny blok oven på stakken, som indeholder værdier, der er specifikke for den pågældende metode, såsom primitive variabler og referencer til objekter.

Når metoden afslutter eksekveringen, tømmes dens tilsvarende stackramme, flowet går tilbage til kaldemetoden, og der bliver plads til den næste metode.

2.1. Nøglefunktioner ved Stack Memory

Nogle andre funktioner i stakhukommelse inkluderer:

  • Det vokser og krymper, efterhånden som nye metoder henholdsvis kaldes og returneres.
  • Variabler inde i stakken eksisterer kun, så længe den metode, der oprettede dem, kører.
  • Den allokeres automatisk og deallokeres automatisk, når metoden afsluttes.
  • Hvis denne hukommelse er fuld, kaster Java java.lang.StackOverFlowError.
  • Adgang til denne hukommelse er hurtig sammenlignet med heap-hukommelse.
  • Denne hukommelse er trådsikker, da hver tråd fungerer i sin egen stak.

3. Heap Space i Java

Heap-plads bruges til dynamisk hukommelsesallokering af Java-objekter og JRE-klasser under kørsel . Nye objekter oprettes altid i heap space, og referencerne til disse objekter gemmes i stakhukommelsen.

Disse objekter har global adgang, og vi kan få adgang til dem hvor som helst i applikationen.

Vi kan opdele denne hukommelsesmodel i mindre dele, kaldet generationer, som er:

  1. Ung generation – det er her alle nye objekter tildeles og ældes. Der sker en mindre affaldsopsamling, når dette fyldes op.
  2. Gamle eller faste generationer – det er her, længe overlevende genstande opbevares. Når objekter gemmes i den unge generation, sættes en tærskel for objektets alder, og når denne tærskel er nået, flyttes objektet til den gamle generation.
  3. Permanent generation – dette består af JVM-metadata for runtime-klasserne og applikationsmetoderne.

Disse forskellige dele er også diskuteret i artiklen Difference Between JVM, JRE og JDK.

Vi kan altid manipulere størrelsen af ​​heap-hukommelse i henhold til vores krav. For mere information, besøg denne linkede Baeldung-artikel.

3.1. Nøglefunktioner i Java Heap Memory

Nogle andre funktioner i heap space inkluderer:

  • Den er tilgået via komplekse hukommelseshåndteringsteknikker, der inkluderer Young Generation, Old eller Tenured Generation og Permanent Generation.
  • Hvis heap-pladsen er fuld, kaster Java java.lang.OutOfMemoryError.
  • Adgang til denne hukommelse er forholdsvis langsommere end stakhukommelse
  • Denne hukommelse bliver, i modsætning til stakken, ikke automatisk deallokeret. Den har brug for Garbage Collector for at frigøre ubrugte genstande for at bevare effektiviteten af ​​hukommelsesforbruget.
  • I modsætning til stakken er en heap ikke trådsikker og skal beskyttes ved korrekt synkronisering af koden.

4. Eksempel

Baseret på det, vi har lært indtil nu, lad os analysere en simpel Java-kode for at vurdere, hvordan man administrerer hukommelse her:

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

Lad os analysere dette trin-for-trin:

  1. Når vi indtaster main() metode, oprettes et rum i stakhukommelsen til at gemme primitiver og referencer for denne metode.
    • Stakhukommelse gemmer direkte den primitive værdi af heltal id.
    • Referencevariablen person af typen Person  vil også blive oprettet i stakhukommelsen, som vil pege på det faktiske objekt i heapen.
  2. Kaldet til den parameteriserede konstruktør Person(int, streng) fra main() vil allokere yderligere hukommelse oven på den forrige stak. Dette vil gemme:
    • Det dette objektreference for det kaldende objekt i stakhukommelsen
    • Den primitive værdi id  i stakhukommelsen
    • Referencevariablen for String argument navn, som vil pege på den faktiske streng fra strengpuljen i heap-hukommelsen
  3. Det vigtigste metoden kalder yderligere buildPerson() statisk metode, for hvilken yderligere allokering vil finde sted i stakhukommelsen oven på den forrige. Dette vil igen gemme variabler på den måde, der er beskrevet ovenfor.
  4. Men heap-hukommelsen gemmer alle instansvariabler for det nyoprettede objekt person af typen Person.

Lad os se på denne tildeling i diagrammet nedenfor:

5. Resumé

Før vi afslutter denne artikel, lad os hurtigt opsummere forskellene mellem Stack Memory og Heap Space:

Parameter Stakhukommelse Heap Space
Ansøgning Stack bruges i dele, én ad gangen under udførelse af en tråd Hele applikationen bruger Heap-plads under kørsel
Størrelse Stack har størrelsesbegrænsninger afhængigt af OS og er normalt mindre end Heap Der er ingen størrelsesbegrænsning på Heap
Lagring Gemmer kun primitive variabler og referencer til objekter, der er oprettet i Heap Space Alle de nyoprettede objekter er gemt her
Bestil Den tilgås ved hjælp af Last-in First-out (LIFO) hukommelsesallokeringssystem Denne hukommelse tilgås via komplekse hukommelseshåndteringsteknikker, der inkluderer Young Generation, Old eller Tenured Generation og Permanent Generation.
Livet Stakhukommelse eksisterer kun, så længe den aktuelle metode kører Den store plads eksisterer, så længe programmet kører
Effektivitet Meget hurtigere at tildele sammenlignet med heap Langsommere at allokere sammenlignet med stak
Tildeling/Deallokering Denne hukommelse tildeles og deallokeres automatisk, når en metode henholdsvis kaldes og returneres Heap-plads tildeles, når nye objekter oprettes og deallokeres af Gargabe Collector, når der ikke længere refereres til dem

6. Konklusion

Stack og heap er to måder, hvorpå Java allokerer hukommelse. I denne artikel lærte vi, hvordan de fungerer, og hvornår de skal bruges til at udvikle bedre Java-programmer.

For at lære mere om Memory Management i Java, se denne artikel her. Vi kom også ind på JVM Garbage Collector, som diskuteres kort i denne artikel.


Java tag