Upravljanje memorijom u Java
⚡ Pametni sažetak
Upravljanje memorijom u Java objašnjava kako JVM dijeli memoriju za vrijeme izvođenja na Stack, Heap, Code, i statičke regije, kako reference objekata teku tijekom poziva metoda i kako Sakupljač smeća vraća nedostižne objekte kako bi aplikacije ostale stabilne i bez curenja memorije.

Što je Stack Memory u Java?
Slaganje memorije u Java je područje JVM memorije koje pohranjuje okvire metoda, lokalne varijable i referentne varijable za svaku nit. Stacku se uvijek pristupa redoslijedom Zadnji unutra, Prvi van, tako da se najnovije pozvana metoda nalazi na vrhu, a njezine lokalne varijable se ubacuju i izbacuju s okvirom.
Svaka nit u Java Virtualni stroj dobiva vlastiti stog (Stog), koji izolirano i sigurno za korištenje u više niti (thread-safe) drži pozive metoda. Primitivne lokalne vrijednosti poput int, boolean i double nalaze se izravno unutar okvira, dok reference objekata pohranjene na stogu (Stog) pokazuju na objekte dodijeljene na hrpi (Heap).
Što je Heap memorija u Java?
Heap memorija je dijeljena JVM regija koja sadrži sve Java objekt i niz stvoreni s operatorom new, zajedno sa svim referentnim varijablama koje pripadaju tim objektima kao poljima instance. Za razliku od Stacka, Heap se dijeli između svih niti, zbog čega pristup objektima često zahtijeva sinkronizaciju.
Heap je područje kojim upravlja Garbage Collector. Moderni HotSpot JVM-ovi dijele Heap na mladu generaciju za kratkotrajne objekte i staru generaciju za dugotrajne objekte, s metapodacima klase pohranjenima u zasebnoj izvornoj regiji koja se zove Metaspace.
Dodjela memorije u Java
Dodjela memorije u Java je proces kojim JVM izdvaja područja virtualne memorije za varijable i instance klasa i struktura tijekom izvršavanja programa. Memorija se ne dodjeljuje objektu prilikom deklaracije; stvara se samo referenca. Stvarna alokacija objekta događa se putem operatora new, tako da se svaki objekt nalazi na hrpi (Heap).
The Java Alokacija memorije podijeljena je na sljedeće dijelove:
- gomila
- Stog
- Code
- statički
Ova podjela memorije je potrebna za učinkovito upravljanje vremenom izvođenja.
- The Code odjeljak sadrži vaše kompilirane bajt.
- The Stog odjeljci trgovina metode, lokalne varijable i referentne varijable.
- The gomila odjeljak sadrži predmeti i može sadržavati i referentne varijable koje se drže kao polja instance.
- The statički odjeljak drži statički podaci i statičke metode dijeljeno u svim instancama.
Razlika između lokalne i varijable instance
Razumijevanje gdje se svaka vrsta varijable nalazi u JVM-u pomaže u objašnjavanju ponašanja Stacka i Heapa. varijabla instance proglašava se unutar klase, ali izvan bilo koje metode, i živi na Heapu kao dio svog objekta.
class Student{ int num; // num is instance variable public void showData{}
A lokalna varijabla proglašava se unutar metode, uključujući argumente metodei nalazi se na stogu unutar aktivnog okvira.
public void sum(int a){ int x = a + 3; // a, x are local variables }
Razlika između hrpe i gomile
Stack i Heap rješavaju različite probleme unutar JVM-a. Stack svakoj niti daje brzu, determinističku alokaciju za kratkotrajne podatke vezane uz opseg metode, dok Heap pruža zajedničko područje za dugotrajne objekte na koje se bilo koja nit može pozivati. Kratki video u nastavku sažima usporedbu prije sljedećeg vodiča.
Kliknite ovdje ako video nije dostupan
Da bismo vidjeli kako Stack i Heap surađuju, razmotrimo glavnu metodu koja poziva metodu m1.
public void m1{ int x = 20; }
U JVM Stacku se kreira okvir za metodu m1.
Varijabla x u m1 također se kreira u okviru za m1 na Stacku, kao što je prikazano na slici ispod.
Metoda m1 zatim poziva metodu m2. U Stacku se stvara novi okvir za m2 povrh okvira za m1.
Lokalne varijable b i c također su kreirane unutar okvira za m2 na Stacku.
public void m2(int b){ boolean c; }
Zatim, m2 poziva metodu m3. Ponovno se okvir za m3 stvara na vrhu stoga, kao što je prikazano dolje.
Recimo sada da metoda m3 stvara objekt za klasu Account, koji ima dva varijable instance int p i int q.
class Account { int p; int q; }
Evo koda za metodu m3.
public void m3(){ Account ref = new Account(); // more code }
Naredba new Account() stvara objekt Account na hrpi.
Referentna varijabla ref kreira se na Stacku unutar okvira za m3.
Operator dodjeljivanja usmjerava referentnu varijablu na objekt na Heap-u.
Nakon što metoda završi izvršavanje, kontrola se vraća pozivajućoj metodi, što je u ovom slučaju metoda m2.
Okvir za metodu m3 se ispire iz Stacka.
Budući da referentna varijabla više ne pokazuje na objekt na Heap-u, taj objekt postaje podoban za sakupljanje smeća.
Nakon što metoda m2 završi, uklanja se sa stoga i sve njezine varijable postaju nedostupne. Isto se događa i za metodu m1, a na kraju se kontrola vraća glavnoj metodi.
Što ako objekt sadrži drugu referencu kao svoju varijablu instance?
public static void main(String args[]) { A parent = new A(); // more code } class A { B child = new B(); int e; } class B { int c; int d; }
U ovom slučaju, referentna varijabla child nalazi se na Heap-u kao dio A objekta i zauzvrat pokazuje na vlastiti B objekt, kao što je prikazano dolje.
U čemu je Garbage Collection Java?
Odvoz smeća u Java je proces kojim JVM automatski upravlja memorijom. Sakupljač smeća pronalazi objekte koji više nisu dostupni iz bilo koje žive reference i vraća im memoriju. Dinamička alokacija memorije događa se putem operatora new, a memorija ostaje alocirana sve dok program više ne sadrži referencu na objekt.
Kada ne preostanu reference, smatra se da objekt više nije potreban, a memorija koju zauzima može se osloboditi. Nema eksplicitne potrebe za uništavanjem objekta jer Java automatski obrađuje dealokaciju putem sakupljača smeća.
Tehnika koja stoji iza ovoga poznata je kao Kolekcija smećaProgrami koji ne uspiju osloboditi memoriju na kraju se sruše kada više nema ništa za dodijeliti. Za takve programe se kaže da imaju memorija propušta. Odvoz smeća u Java pokreće se automatski tijekom cijelog životnog vijeka programa, što uklanja teret ručne dealokacije i smanjuje rizik od curenja.
U C-u, nasuprot tome, programer je odgovoran za oslobađanje memorije dodijeljene dinamički putem funkcije free(). Ovdje Java Upravljanje memorijom nudi snažnu prednost.
Moderni HotSpot JVM-ovi isporučuju nekoliko Garbage Collectora podešenih za različita opterećenja. Zadani G1 Garbage Collector cilja uravnoteženu propusnost i vremena pauze na hrpama od više gigabajta. ZGC i Shenandoah ciljaju na pauze ispod milisekunde na vrlo velikim hrpama, što ih čini...tracposebno za usluge osjetljive na latenciju. Odabir pravog kolektora i podešavanje veličina mlade generacije, stare generacije i metaprostora ključna je vještina za Java performans rad.
Bilješka: Svi objekti se stvaraju u dijelu memorije Heap, što je područje kojim upravlja Garbage Collector.
Primjer: Naučiti mehanizam skupljača smeća u Java
Ovaj vodič pokazuje kada reference postaju prihvatljive za sakupljanje smeća unutar jednostavnog programa.
Korak 1) Kopirajte sljedeći kod u editor.
class Student{ int a; int b; public void setData(int c,int d){ a=c; b=d; } public void showData(){ System.out.println("Value of a = "+a); System.out.println("Value of b = "+b); } public static void main(String args[]){ Student s1 = new Student(); Student s2 = new Student(); s1.setData(1,2); s2.setData(3,4); s1.showData(); s2.showData(); //Student s3; //s3=s2; //s3.showData(); //s2=null; //s3.showData(); //s3=null; //s3.showData(); } }
Korak 2) Spremite, kompajlirajte i pokrenite kod. Kao što je prikazano na dijagramu, kreirana su dva objekta i dvije referentne varijable.
Korak 3) Uklonite komentare iz redaka 20, 21 i 22. Spremite, kompajlirajte i pokrenite kod.
Korak 4) Kao što je prikazano na donjem dijagramu, dvije referentne varijable sada pokazuju na isti objekt.
Korak 5) Uklonite komentare iz redaka 23 i 24. Spremite, kompajlirajte i pokrenite kod.
Korak 6) Kao što je prikazano dolje, s2 postaje null, ali s3 i dalje pokazuje na objekt, tako da objekt još nije podoban za sakupljanje smeća.
Korak 7) Uklonite komentare iz redaka 25 i 26. Spremite, kompajlirajte i pokrenite kod.
Korak 8) U ovom trenutku, nijedna referenca ne upućuje na objekt, pa on postaje podoban za sakupljanje smeća. Sakupljač smeća ga uklanja iz memorije i ne postoji način da ga se dohvati.
Kako izbrisati objekt u Java?
Java ne pruža operator ručnog brisanja, pa je standardni pristup uklanjanje svake reference na objekt kako bi ga sakupljač smeća mogao ponovno zatražiti.
1) Da biste objekt učinili prihvatljivim za sakupljanje smeća, svakoj referentnoj varijabli koja pokazuje na njega dodijelite vrijednost null.
2) Primitivni tipovi nisu objekti, stoga im se ne može dodijeliti vrijednost null. Njihov prostor se automatski oslobađa kada se okolni Stack okvir otvori.


















