Hukommelseshåndtering i Java
⚡ Smart opsummering
Hukommelseshåndtering i Java forklarer, hvordan JVM'en opdeler runtime-hukommelse på tværs af Stack, Heap, Code, og statiske regioner, hvordan objektreferencer flyder under metodekald, og hvordan Garbage Collector genvinder uopnåelige objekter, så applikationer forbliver stabile og fri for hukommelseslækager.
Hvad er stakhukommelse i Java?
Stak hukommelse i Java er det område af JVM-hukommelsen, der lagrer metoderammer, lokale variabler og referencevariabler for hver tråd. Stakken tilgås altid i rækkefølgen "Sidst ind, Først ud", så den senest kaldede metode sidder øverst, og dens lokale variabler pushes og poppes sammen med rammen.
Hver tråd i Java Den virtuelle maskine modtager sin egen stak, som isolerer og trådsikrer metodekald per design. Primitive lokale værdier som int, boolean og double findes direkte inde i rammen, mens objektreferencer gemt på stakken peger på objekter allokeret på heapen.
Hvad er Heap Memory i Java?
Heaphukommelse er den delte JVM-region, der indeholder alle Java objekt og array oprettet med den nye operator, sammen med eventuelle referencevariabler, der tilhører disse objekter som instansfelter. I modsætning til Stack deles Heap på tværs af alle tråde, hvilket er grunden til, at objektadgang ofte kræver synkronisering.
Heapen er det område, som Garbage Collector administrerer. Moderne HotSpot JVM'er opdeler Heapen i en Young Generation for kortlivede objekter og en Old Generation for langlivede objekter, hvor klassemetadata gemmes i en separat, oprindelig region kaldet Metaspace.
Hukommelsestildeling ind Java
Hukommelsestildeling ind Java er den proces, hvorved JVM'en afsætter virtuelle hukommelsesområder til variabler og instanser af klasser og strukturer under programudførelse. Hukommelsen allokeres ikke til et objekt ved deklaration; kun en reference oprettes. Den faktiske objektallokering sker via new-operatoren, så hvert objekt findes på heapen.
Java Hukommelsesallokering er opdelt i følgende sektioner:
- bunke
- Stak
- Code
- statisk
Denne opdeling af hukommelse er nødvendig for effektiv styring af runtime.
- Code afsnittet indeholder dine kompilerede bytekode.
- Stak sektionsbutikker metoder, lokale variabler og referencevariabler.
- bunke afsnit indeholder objekter og kan også indeholde referencevariabler, der holdes som instansfelter.
- statisk sektionshold statiske data og statiske metoder delt på tværs af alle instanser.
Forskellen mellem lokal og instansvariabel
At forstå, hvor hver type variabel befinder sig i JVM'en, hjælper med at forklare Stack- og Heap-adfærd. instansvariabel erklæres inden for en klasse, men uden for enhver metode, og den lever på Høngen som en del af dens objekt.
class Student{ int num; // num is instance variable public void showData{}
A lokal variabel erklæres inde i en metode, inklusive metodeargumenter, og ligger på stakken inde i den aktive ramme.
public void sum(int a){ int x = a + 3; // a, x are local variables }
Forskellen mellem stak og heap
Stack og Heap løser forskellige problemer i JVM'en. Stack giver hver tråd hurtig, deterministisk allokering af kortlivede data knyttet til metodeomfang, mens Heap giver et delt område for langlivede objekter, som enhver tråd kan referere til. Den korte video nedenfor opsummerer kontrasten før den følgende gennemgang.
Klik link. hvis videoen ikke er tilgængelig
For at se, hvordan Stack og Heap samarbejder, kan man betragte en hovedmetode, der kalder metode m1.
public void m1{ int x = 20; }
I JVM-stakken oprettes en frame til metode m1.
Variablen x i m1 oprettes også i rammen for m1 på stakken, som vist på billedet nedenfor.
Metode m1 kalder derefter metode m2. I stakken oprettes en ny ramme for m2 oven på rammen for m1.
De lokale variabler b og c oprettes også inde i rammen for m2 på stakken.
public void m2(int b){ boolean c; }
Dernæst kalder m2 metoden m3. Igen oprettes en frame til m3 øverst i stakken, som vist nedenfor.
Lad os nu sige, at metode m3 opretter et objekt for klassen Account, som har to instansvariabler int p og int q.
class Account { int p; int q; }
Her er koden til metode m3.
public void m3(){ Account ref = new Account(); // more code }
Udtrykket new Account() opretter et objekt af typen Account på heapen.
Referencevariablen ref oprettes på stakken inde i rammen for m3.
Tildelingsoperatoren får referencevariablen til at pege på objektet på heapen.
Når metoden er udført, vender kontrollen tilbage til den kaldende metode, som i dette tilfælde er metode m2.
Rammen for metode m3 skylles ud af stakken.
Da referencevariablen ikke længere peger på objektet på heapen, bliver dette objekt berettiget til garbage collection.
Når metode m2 er færdig, fjernes den fra stakken, og alle dens variabler bliver utilgængelige. Det samme sker for metode m1, og til sidst vender kontrollen tilbage til hovedmetoden.
Hvad hvis et objekt har en anden reference som sin instansvariabel?
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; }
I dette tilfælde findes referencevariablen "child" på Heap som en del af A-objektet og peger til gengæld på sit eget B-objekt, som vist nedenfor.
Hvad er Garbage Collection i Java?
Affaldsopsamling i Java er den proces, hvorved JVM'en automatisk udfører hukommelsesstyring. Garbage Collector finder objekter, der ikke længere kan nås fra nogen live-reference, og generobrer deres hukommelse. Dynamisk hukommelsesallokering sker via den nye operator, og hukommelsen forbliver allokeret, indtil programmet ikke længere har nogen reference til objektet.
Når der ikke længere er nogen referencer tilbage, anses objektet for ikke længere nødvendigt, og den hukommelse, det optager, kan genvindes. Der er ikke noget eksplicit behov for at ødelægge et objekt, fordi Java håndterer deallokeringen automatisk via Garbage Collector.
Teknikken bag dette er kendt som DagrenovationProgrammer, der ikke frigiver hukommelse, går ned, når der ikke er noget tilbage at allokere. Sådanne programmer siges at have hukommelse lækker. Affaldsopsamling i Java kører automatisk i hele programmets levetid, hvilket fjerner byrden ved manuel deallokering og reducerer risikoen for lækager.
I C er programmøren derimod ansvarlig for at frigive hukommelse allokeret dynamisk via free()-funktionen. Det er her Java Hukommelsesstyring tilbyder en stor fordel.
Moderne HotSpot JVM'er leveres med adskillige Garbage Collectors, der er indstillet til forskellige arbejdsbelastninger. Standard G1 Garbage Collector sigter mod balanceret gennemløbshastighed og pausetider på heaps på flere gigabyte. ZGC og Shenandoah sigter mod pauser på under et millisekund på meget store heaps, hvilket gør dem påtractiv til latenstidsfølsomme tjenester. At vælge den rigtige samler og justere størrelserne for den unge generation, den gamle generation og metaspace er en kernefærdighed for Java performancearbejde.
Bemærk: Alle objekter oprettes i Heap-sektionen af hukommelsen, som er den region, som Garbage Collector administrerer.
Eksempel: At lære affaldsopsamlermekanisme i Java
Denne gennemgang viser, hvornår referencer bliver berettigede til Garbage Collection i et simpelt program.
Trin 1) Kopier følgende kode ind i en 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(); } }
Trin 2) Gem, kompiler og kør koden. Som vist i diagrammet oprettes to objekter og to referencevariabler.
Trin 3) Fjern kommentaren fra linje 20, 21 og 22. Gem, kompiler og kør koden.
Trin 4) Som vist i diagrammet nedenfor peger to referencevariabler nu på det samme objekt.
Trin 5) Fjern kommentaren fra linje 23 og 24. Gem, kompiler og kør koden.
Trin 6) Som vist nedenfor bliver s2 null, men s3 peger stadig på objektet, så objektet er endnu ikke berettiget til Garbage Collection.
Trin 7) Fjern kommentaren fra linje 25 og 26. Gem, kompiler og kør koden.
Trin 8) På dette tidspunkt peger ingen referencer på objektet, så det bliver berettiget til Garbage Collection. Garbage Collector fjerner det fra hukommelsen, og der er ingen måde at hente det på.
Sådan sletter du et objekt i Java?
Java tilbyder ikke en manuel sletteoperator, så standardmetoden er at fjerne alle referencer til objektet, så Garbage Collector kan genvinde det.
1) For at gøre et objekt berettiget til Garbage Collection, skal du tildele alle referencevariabler, der peger på det, til null.
2) Primitive typer er ikke objekter, så de kan ikke tildeles null. Deres lagerplads genvindes automatisk, når den omgivende Stack-ramme poppes.



















