Mäluhaldus sisse Java
⚡ Nutikas kokkuvõte
Mäluhaldus sisse Java selgitab, kuidas JVM jagab käitusaja mälu pinu, kuhja ja muu vahel. Codeja staatilisi piirkondi, kuidas objektiviited meetodikõnede ajal voolavad ja kuidas prügikoguja kättesaamatuid objekte taastab, et rakendused püsiksid stabiilsed ja mäluleketeta.
Mis on pinumälu? Java?
Mälu virn Java on JVM-i mälu piirkond, mis salvestab iga lõime meetodi raame, lokaalseid muutujaid ja viitemuutujaid. Stackile pääseb alati juurde järjekorras viimane-sisene-esimene-välja, seega on viimati käivitatud meetod peal ning selle lokaalsed muutujad lükatakse ja ilmuvad koos kaadriga.
Iga niit selles Java Virtuaalmasin saab oma Stacki, mis hoiab meetodite kutsumised isoleerituna ja lõimekindlalt. Primitiivsed lokaalid, näiteks int, boolean ja double, asuvad otse raami sees, samas kui Stackis talletatud objektiviited osutavad Heapil eraldatud objektidele.
Mis on kuhjamälu? Java?
Heap-mälu on jagatud JVM-i piirkond, mis sisaldab kõiki Java new operaatoriga loodud objekt ja massiiv koos kõigi nende objektidega kaasnevate viitemuutujatega eksemplariväljadena. Erinevalt pinust (Spin) jagatakse Heapi (Heap) kõigi lõimede vahel, mistõttu objektidele juurdepääs nõuab sageli sünkroniseerimist.
Heap on ala, mida prügikoguja haldab. Kaasaegsed HotSpot JVM-id jagavad Heapi lühikese elueaga objektide jaoks mõeldud nooreks põlvkonnaks ja pika elueaga objektide jaoks vanaks põlvkonnaks, kusjuures klassi metaandmed salvestatakse eraldi natiivsesse piirkonda nimega Metaspace.
Mälu eraldamine sisse Java
Mälu eraldamine sisse Java on protsess, mille käigus JVM eraldab programmi täitmise ajal virtuaalmälu piirkonnad muutujate ja klasside ning struktuuride eksemplaride jaoks. Mälu ei eraldata objektile deklareerimisel; luuakse ainult viide. Tegelik objekti eraldamine toimub uue operaatori kaudu, seega asub iga objekt heapis.
. Java Mälu eraldamine on jagatud järgmisteks osadeks:
- hunnik
- Stack
- Code
- Staatiline
See mälujaotus on vajalik käituskeskkonna tõhusaks haldamiseks.
- . Code jaotis sisaldab teie kompileeritud baitkood.
- . Stack osakonna kauplused meetodid, lokaalsed muutujad ja võrdlusmuutujad.
- . hunnik jaotis sisaldab esemeid ja võib sisaldada ka viitemuutujaid, mida hoitakse eksemplariväljadena.
- . Staatiline sektsiooni hoidmised staatilised andmed ja staatilised meetodid jagatud kõigis eksemplarides.
Erinevus kohaliku ja eksemplari muutuja vahel
Iga muutujatüübi asukoha mõistmine JVM-is aitab selgitada Stacki ja Heapi käitumist. eksemplari muutuja deklareeritakse klassi sees, aga väljaspool mis tahes meetoditja see elab Kuhjal oma objekti osana.
class Student{ int num; // num is instance variable public void showData{}
A kohalik muutuja deklareeritakse meetodi sees, sealhulgas meetodi argumendidja asub aktiivse raami sees olevas Stackis.
public void sum(int a){ int x = a + 3; // a, x are local variables }
Erinevus virna ja kuhja vahel
Stack ja Heap lahendavad JVM-is erinevaid probleeme. Stack annab igale lõimele kiire ja deterministliku jaotuse lühiajaliste andmete jaoks, mis on seotud meetodi ulatusega, samas kui Heap pakub jagatud piirkonda pikaajaliste objektide jaoks, millele iga lõim saab viidata. Allolev lühike video võtab kokku erinevused enne järgnevat läbimängu.
Click siin kui video pole juurdepääsetav
Stacki ja Heapi koostöö nägemiseks vaatleme peameetodit, mis kutsub esile meetodi m1.
public void m1{ int x = 20; }
JVM Stackis luuakse meetodi m1 jaoks raam.
Muutuja x muutujas x luuakse ka muutuja m1 raamis pinus, nagu on näidatud alloleval pildil.
Seejärel kutsub meetod m1 välja meetodi m2. Stackis luuakse m2 jaoks uus kaader m1 kaadri peale.
Kohalikud muutujad b ja c luuakse ka pinu m2 raami sees.
public void m2(int b){ boolean c; }
Järgmisena kutsub m2 välja meetodi m3. Jällegi luuakse pinu peale m3 jaoks raam, nagu allpool näidatud.
Oletame nüüd, et meetod m3 loob objekti klassile Account, millel on kaks eksemplari muutujad int p ja int q.
class Account { int p; int q; }
Siin on meetodi m3 kood.
public void m3(){ Account ref = new Account(); // more code }
Lause new Account() loob heapisse Account objekti.
Viitemuutuja ref luuakse m3 jaoks raami sees olevas pinus.
Omistusoperaator paneb viitemuutuja osutama heapil olevale objektile.
Kui meetod on täitmise lõpetanud, naaseb juhtimine kutsuva meetodi juurde, milleks antud juhul on meetod m2.
Meetodi m3 raam tühjendatakse pinust.
Kuna viitemuutuja ei osuta enam heapil olevale objektile, muutub see objekt prügikoristuseks kõlblikuks.
Kui meetod m2 on lõppenud, eemaldatakse see pinust ja kõik selle muutujad muutuvad kättesaamatuks. Sama juhtub meetodi m1 puhul ja lõpuks naaseb juhtimine põhimeetodi juurde.
Mis saab siis, kui objekti eksemplarimuutujana on mõni muu viide?
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; }
Sel juhul asub viitemuutuja laps heapil A-objekti osana ja osutab omakorda omaenda B-objektile, nagu allpool näidatud.
Mis on prügikoristus Java?
Prügi kogumine sisse Java on protsess, mille käigus JVM teostab automaatselt mäluhaldust. Prügikoguja leiab objektid, mis pole enam ühegi reaalajas viite kaudu kättesaadavad, ja vabastab nende mälu. Dünaamiline mälu eraldamine toimub uue operaatori kaudu ja mälu jääb eraldatuks seni, kuni programmil pole enam objektile ühtegi viidet.
Kui viiteid enam ei ole, loetakse objekti enam mittevajalikuks ja selle poolt hõivatud mälu saab taastada. Objekti hävitamiseks pole otsest vajadust, sest Java tegeleb tehingute jaotamisega automaatselt prügikoguja kaudu.
Selle taga olev tehnika on tuntud kui PrügikoguProgrammid, mis ei suuda mälu vabastada, jooksevad lõpuks kokku, kui midagi enam eraldada ei jää. Selliste programmide kohta öeldakse, et neil on mälu lekib. Prügi kogumine sisse Java töötab automaatselt kogu programmi eluea jooksul, mis kõrvaldab käsitsi tehingute jaotamise koormuse ja vähendab lekete ohtu.
C-keeles seevastu vastutab programmeerija dünaamiliselt free() funktsiooni kaudu eraldatud mälu vabastamise eest. Siin on koht, kus Java mäluhaldus pakub tugevat eelist.
Kaasaegsed HotSpot JVM-id on varustatud mitme prügikogujaga, mis on häälestatud erinevate töökoormuste jaoks. Vaikimisi G1 prügikoguja eesmärk on tasakaalustatud läbilaskevõime ja pausiajad mitme gigabaidiste kuhjade puhul. ZGC ja Shenandoah püüavad saavutada millisekundilisi pause väga suurte kuhjade puhul, mis teeb nad ...traclatentsustundlike teenuste jaoks. Õige koguja valimine ja noore põlvkonna, vana põlvkonna ja metaruumi suuruste häälestamine on põhioskus Java etendustöö.
Märge: Kõik objektid luuakse mälu Heap-osas, mis on piirkond, mida prügikoguja haldab.
Näide: Prügikogumismehhanismi õppimiseks Java
See läbivaatus näitab, millal viited lihtsa programmi sees prügikoristuseks sobivad.
Step 1) Kopeerige järgmine kood redaktorisse.
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(); } }
Step 2) Salvesta, kompileeri ja käivita kood. Nagu diagrammil näidatud, luuakse kaks objekti ja kaks viitemuutujat.
Step 3) Eemalda kommentaarid ridadelt 20, 21 ja 22. Salvesta, kompileeri ja käivita kood.
Step 4) Nagu alloleval diagrammil näidatud, osutavad kaks viitemuutujat nüüd samale objektile.
Step 5) Eemalda kommentaarid ridadelt 23 ja 24. Salvesta, kompileeri ja käivita kood.
Step 6) Nagu allpool näidatud, muutub s2 nulliks, kuid s3 osutab endiselt objektile, seega pole objekt veel prügikoristuseks kõlblik.
Step 7) Eemalda kommentaarid ridadelt 25 ja 26. Salvesta, kompileeri ja käivita kood.
Step 8) Sel hetkel ei osuta objektile enam ükski viide, seega muutub see prügikoristuseks kõlblikuks. Prügikorjaja eemaldab selle mälust ja seda pole enam võimalik taastada.
Kuidas objekti kustutada Java?
Java ei paku käsitsi kustutamise operaatorit, seega on standardmeetodiks eemaldada kõik viited objektile, et prügikoguja saaks selle taastada.
1) Prügikoristuseks sobivaks objektiks määrake iga sellele osutav viitemuutuja väärtuseks null.
2) Primitiivsed tüübid ei ole objektid, seega ei saa neile määrata nullväärtust. Nende salvestusruum vabaneb automaatselt, kui ümbritsev Stack-raam hüpatakse välja.



















