Skladať pamäť a kopu priestoru v Jave

1. Úvod

Ak chcete spustiť aplikáciu optimálnym spôsobom, JVM rozdelí pamäť na pamäť typu stack a haldy. Kedykoľvek deklarujeme nové premenné a objekty, zavolajte novú metódu, deklarujte a String alebo vykonávať podobné operácie, JVM označuje pamäť pre tieto operácie buď zo zásobníka pamäte, alebo z haldy.

V tomto výučbe si rozoberieme tieto pamäťové modely. Zaradíme medzi ne niektoré kľúčové rozdiely, ako sú uložené v pamäti RAM, aké funkcie ponúkajú a kde ich používať.

2. Ukladanie pamäte do Javy

Stack Memory v Jave sa používa na statické prideľovanie pamäte a vykonávanie vlákna. Obsahuje primitívne hodnoty, ktoré sú špecifické pre metódu, a odkazy na objekty, ktoré sú v halde, odkázané z metódy.

Prístup k tejto pamäti je v poradí Last-In-First-Out (LIFO). Kedykoľvek sa zavolá nová metóda, vytvorí sa nový blok na vrchu zásobníka, ktorý obsahuje hodnoty špecifické pre túto metódu, ako sú primitívne premenné a odkazy na objekty.

Keď metóda dokončí vykonávanie, zodpovedajúci rámec zásobníka sa vyprázdni, tok sa vráti späť k metóde volania a bude k dispozícii priestor pre ďalšiu metódu.

2.1. Kľúčové vlastnosti zásobníka pamäte

Okrem toho, o čom sme doteraz hovorili, sú nasledujúce ďalšie funkcie pamäte zásobníka:

  • Rastie a zmenšuje sa, keď sa volajú a vracajú nové metódy
  • Premenné v zásobníku existujú iba dovtedy, kým je spustená metóda, ktorá ich vytvorila
  • Automaticky sa pridelí a uvoľní sa, keď metóda dokončí vykonávanie
  • Ak je táto pamäť plná, hodí sa Java java.lang.StackOverFlowError
  • Prístup k tejto pamäti je rýchly v porovnaní s hromadnou pamäťou
  • Táto pamäť je bezpečná pre vlákna, pretože každé vlákno pracuje vo svojom vlastnom zásobníku

3. Heap Space v Jave

Haldy v prostredí Java sa používajú na dynamické prideľovanie pamäte pre objekty Java a triedy JRE za behu programu. Nové objekty sa vždy vytvárajú v halde a odkazy na tieto objekty sa ukladajú do pamäte zásobníka.

Tieto objekty majú globálny prístup a je k nim možné pristupovať z ľubovoľného miesta v aplikácii.

Tento pamäťový model je ďalej rozdelený na menšie časti nazývané generácie, ktorými sú:

  1. Mladá generácia - tu sa prideľujú a starnú všetky nové objekty. Keď sa to naplní, dôjde k menšiemu zberu odpadu
  2. Stará alebo oprávnená generácia - tu sa ukladajú dlho prežívajúce predmety. Keď sú objekty uložené v mladej generácii, nastaví sa prahová hodnota pre vek objektu a po dosiahnutí tejto prahovej hodnoty sa objekt presunie do starej generácie
  3. Stála generácia - pozostáva z metadát JVM pre triedy runtime a aplikačné metódy

O týchto rôznych častiach pojednáva aj tento článok - Rozdiel medzi JVM, JRE a JDK.

S veľkosťou haldy pamäte môžeme kedykoľvek manipulovať podľa našich požiadaviek. Viac informácií nájdete v tomto prepojenom článku o Baeldungu.

3.1. Kľúčové vlastnosti haldy pamäte Java

Okrem toho, o čom sme doteraz hovorili, sú tu aj ďalšie vlastnosti haldy:

  • Je prístupný prostredníctvom komplexných techník správy pamäte, ktoré zahŕňajú mladú generáciu, starú alebo tenurovanú generáciu a permanentnú generáciu
  • Ak je halda plná, Java hodí java.lang.OutOfMemoryError
  • Prístup k tejto pamäti je relatívne pomalší ako k zásobníku
  • Na rozdiel od zásobníka nie je táto pamäť automaticky uvoľnená. Potrebuje program Garbage Collector, aby uvoľnil nepoužívané objekty, aby sa udržala efektivita využitia pamäte
  • Na rozdiel od zásobníka nie je hromada bezpečná pre vlákna a je potrebné ju strážiť správnou synchronizáciou kódu

4. Príklad

Na základe toho, čo sme sa doteraz naučili, poďme analyzovať jednoduchý kód Java a posúdime, ako sa tu spravuje pamäť:

trieda Osoba {int id; Názov reťazca; public Person (int id, String name) {this.id = id; this.name = meno; }} 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; Názov reťazca = "John"; Osoba osoba = null; osoba = buildPerson (id, meno); }}

Poďme si to podrobne rozobrať:

  1. Pri vstupe do hlavný() by sa v zásobníku vytvorila medzera na ukladanie primitív a odkazov na túto metódu
    • Primitívna hodnota celého čísla id budú uložené priamo v zásobníku
    • Referenčná premenná osoba typu Osoba sa tiež vytvorí v zásobníku, ktorá bude ukazovať na skutočný objekt v halde
  2. Volanie parametrizovaného konštruktora Osoba (int, reťazec) od hlavný() pridelí ďalšiu pamäť nad predchádzajúci zásobník. Toto uloží:
    • The toto referencia objektu volajúceho objektu v zásobníku
    • Primitívna hodnota id v pamäti zásobníka
    • Referenčná premenná String argument názov , ktoré ukážu na skutočný reťazec z fondu reťazcov v halde pamäte
  3. The hlavný metóda ďalej volá buildPerson () statická metóda, pre ktorú bude ďalšie prideľovanie prebiehať v zásobníku nad predchádzajúcou. To opäť uloží premenné vyššie opísaným spôsobom.
  4. Avšak pre novovytvorený objekt osoba typu Osoba, všetky premenné inštancie budú uložené v halde pamäte.

Toto rozdelenie je vysvetlené v tomto diagrame:

5. Zhrnutie

Predtým, ako uzavrieme tento článok, poďme rýchlo zhrnúť rozdiely medzi Stack Memory a Heap Space:

ParameterUložiť pamäťHalda vesmíru
AplikáciaZásobník sa používa v častiach, jeden po druhom počas vykonávania vláknaCelá aplikácia využíva počas behu priestoru haldy
VeľkosťZásobník má limity veľkosti v závislosti od operačného systému a je zvyčajne menší ako hromadaNa halde nie je žiadny limit veľkosti
SkladovanieUkladá iba primitívne premenné a odkazy na objekty, ktoré sú vytvorené v haldeTu sú uložené všetky novo vytvorené objekty
objednaťJe k nim prístup pomocou systému prideľovania pamäte Last-in First-out (LIFO)Táto pamäť je prístupná prostredníctvom komplexných techník správy pamäte, ktoré zahŕňajú mladú generáciu, starú alebo oprávnenú generáciu a permanentnú generáciu.
ŽivotZásobníková pamäť existuje iba dovtedy, kým je spustená aktuálna metódaHalda existuje, pokiaľ je aplikácia spustená
ÚčinnosťPomerne rýchlejšie sa prideľuje v porovnaní s hromadouPomalšie alokácia v porovnaní so zásobníkom
Pridelenie / pridelenieTáto pamäť je automaticky pridelená a uvoľnená, keď sa metóda volá a vraciaHalda priestoru je pridelená, keď sú nové objekty vytvorené a uvoľnené Gargabe Collector, keď už na ne nie je odkaz

6. Záver

Zásobník a halda sú dva spôsoby, ktorými Java alokuje pamäť. V tomto článku sme pochopili, ako fungujú a kedy ich použiť na vývoj lepších programov Java.

Ak sa chcete dozvedieť viac informácií o správe pamäte v prostredí Java, pozrite si tento článok tu. Diskutovali sme tiež o zberači odpadu JVM, o ktorom sa v krátkosti pojednáva v tomto článku.