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.



















