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ú:
- Mladá generácia - tu sa prideľujú a starnú všetky nové objekty. Keď sa to naplní, dôjde k menšiemu zberu odpadu
- 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
- 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ť:
- 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
- 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
- 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.
- 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:
Parameter | Uložiť pamäť | Halda vesmíru |
---|---|---|
Aplikácia | Zásobník sa používa v častiach, jeden po druhom počas vykonávania vlákna | Celá 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 hromada | Na halde nie je žiadny limit veľkosti |
Skladovanie | Ukladá iba primitívne premenné a odkazy na objekty, ktoré sú vytvorené v halde | Tu 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. |
Život | Zásobníková pamäť existuje iba dovtedy, kým je spustená aktuálna metóda | Halda existuje, pokiaľ je aplikácia spustená |
Účinnosť | Pomerne rýchlejšie sa prideľuje v porovnaní s hromadou | Pomalšie alokácia v porovnaní so zásobníkom |
Pridelenie / pridelenie | Táto pamäť je automaticky pridelená a uvoľnená, keď sa metóda volá a vracia | Halda 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.