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.

  • ๐Ÿง  Raspored JVM memorije: Java Memorija je podijeljena na Heap za objekte, Stack za okvire metoda i lokalne varijable, plus namjenska podruฤja za bajtkod i statiฤke podatke.
  • ๐Ÿ“š Stog u odnosu na hrpu: Okviri slaganja slijede redoslijed Zadnji unutra, Prvi van i pohranjuju primitive i reference, dok Heap sadrลพi svaki objekt stvoren operatorom new.
  • โ™ป๏ธ Kolekcija smeฤ‡a: Sakupljaฤ smeฤ‡a tracks dostiลพnost kroz referentne lance i automatski vraฤ‡a memoriju od objekata do kojih nijedna nit ne moลพe doฤ‡i.
  • โœ… Moderni kolekcionari: Produkcijska optereฤ‡enja sve se viลกe oslanjaju na G1, ZGC i Shenandoah za prikupljanje s niskom pauzom na hrpama od viลกe gigabajta.
  • ๐Ÿงช Praktiฤni primjer: Detaljan vodiฤ za studente pokazuje kada reference postaju prihvatljive za kolekciju i kako poniลกtavanje referenci oslobaฤ‘a temeljni objekt.

Upravljanje memorijom u Java

ล 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:

  1. gomila
  2. Stog
  3. Code
  4. 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.

Java Stog i gomila

Varijabla x u m1 takoฤ‘er se kreira u okviru za m1 na Stacku, kao ลกto je prikazano na slici ispod.

Java Stog i gomila

Metoda m1 zatim poziva metodu m2. U Stacku se stvara novi okvir za m2 povrh okvira za m1.

Java Stog i gomila

Java Stog i gomila

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.

Java Stog i gomila

Java Stog i gomila

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.

Java Stog i gomila

Referentna varijabla ref kreira se na Stacku unutar okvira za m3.

Java Stog i gomila

Operator dodjeljivanja usmjerava referentnu varijablu na objekt na Heap-u.

Java Stog i gomila

Nakon ลกto metoda zavrลกi izvrลกavanje, kontrola se vraฤ‡a pozivajuฤ‡oj metodi, ลกto je u ovom sluฤaju metoda m2.

Java Stog i gomila

Okvir za metodu m3 se ispire iz Stacka.

Java Stog i gomila

Buduฤ‡i da referentna varijabla viลกe ne pokazuje na objekt na Heap-u, taj objekt postaje podoban za sakupljanje smeฤ‡a.

Java Stog i gomila

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.

Java Stog i gomila

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.

 Mehanizam sakupljaฤa smeฤ‡a

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.

Mehanizam sakupljaฤa smeฤ‡a

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.

 Mehanizam sakupljaฤa 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.

 Nauฤite skupljaฤa smeฤ‡a

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.

Kako izbrisati objekt u Java

Pitanja i odgovori

Stack pohranjuje okvire metoda, lokalne varijable i reference redoslijedom "zadnji uลกao, prvi izaลกao" po niti. Heap pohranjuje sve objekte stvorene s new i dijeli se meฤ‘u nitima, zbog ฤega njime upravlja Garbage Collector.

Sakupljaฤ smeฤ‡a obilazi referentne lance od korijena GC-a kao ลกto su aktivne niti i statiฤka polja. Bilo koji objekt koji se ne moลพe dosegnuti iz korijena smatra se nedostiลพnim i postaje podoban za ponovno koriลกtenje tijekom sljedeฤ‡eg ciklusa sakupljanja.

Mlada generacija sadrลพi kratkotrajne objekte u prostorima Eden i Survivor. Stara generacija sadrลพi objekte koji preลพivljavaju viลกe kolekcija. Metaprostor je podruฤje izvorne memorije koje pohranjuje metapodatke klase i zamijenilo je stariji PermGen u Java 8.

G1 je zadana postavka i odgovara veฤ‡ini optereฤ‡enja na hrpama od viลกe gigabajta. ZGC i Shenandoah ciljaju pauze kraฤ‡e od milisekunde na vrlo velikim hrpama i dobar su izbor za usluge osjetljive na latenciju koje se izvode na Java 17 ili noviji.

Postavite svaku referencu koja pokazuje na objekt na null ili dopustite da reference ispadnu izvan dosega kada se njihovi Stack okviri izostave. Nakon ลกto nijedna ลพiva referenca ne dosegne objekt, Garbage Collector vraฤ‡a svoju Heap memoriju.

Da. Alati za podeลกavanje voฤ‘eni umjetnom inteligencijom analiziraju GC zapise, stope alokacije i histograme pauziranja kako bi preporuฤili veliฤine hrpe, zastavice kolektora i omjere mlade generacije. Oni skraฤ‡uju petlju povratne informacije u usporedbi s ruฤnim podeลกavanjem, posebno kod optereฤ‡enja G1, ZGC i Shenandoah.

Platforme za promatranje temeljene na umjetnoj inteligenciji unoลกenjem heap podataka i metriฤkih podataka uลพivo, a zatim grupiranjem grafova zadrลพanih objekata oznaฤava sumnjive klase i lance referenci. To brลพe otkriva kandidate za curenje nego ruฤna analiza heap podataka i pomaลพe timovima da utvrde uzrok u produkciji.

Saลพmite ovu objavu uz: