Minnehåndtering i Java-intervjuspørsmål (+ svar)

Denne artikkelen er en del av en serie: • Java Collections Interview Questions

• Java Type System Interview Questions

• Java-samtalespørsmål om samtidighet (+ svar)

• Spørsmål om Java-klassestruktur og initialisering

• Java 8 intervjuspørsmål (+ svar)

• Minnehåndtering i Java-intervjuspørsmål (+ svar) (nåværende artikkel) • Java Generics-intervjuspørsmål (+ svar)

• Intervju med Java Flow Control (+ svar)

• Java-unntaksspørsmål (+ svar)

• Spørsmål om Java-merknader (+ svar)

• Spørsmål om topp vårrammeverk

1. Introduksjon

I denne artikkelen vil vi utforske noen spørsmål om minnestyring som ofte dukker opp under Java-utviklerintervjuer. Minnehåndtering er et område som ikke så mange utviklere er kjent med.

Faktisk trenger ikke utviklere generelt å håndtere dette konseptet direkte - da JVM tar seg av de detaljerte detaljene. Med mindre noe går alvorlig galt, har kanskje også erfarne utviklere ikke nøyaktig informasjon om minnestyring innen fingertuppene.

På den annen side er disse konseptene faktisk ganske utbredte i intervjuer - så la oss hoppe rett inn.

2. Spørsmål

Q1. Hva betyr utsagnet "Minne administreres i Java"?

Minne er nøkkelressursen et program krever for å kjøre effektivt, og som enhver ressurs er det lite. Som sådan krever tildeling og avtale til og fra applikasjoner eller forskjellige deler av en applikasjon mye omsorg og omtanke.

Imidlertid, i Java, trenger ikke en utvikler å eksplisitt tildele og distribuere minne - JVM og mer spesifikt Garbage Collector - har plikten til å håndtere minnetildeling slik at utvikleren ikke trenger å gjøre det.

Dette er i strid med hva som skjer på språk som C der en programmerer har direkte tilgang til minne og bokstavelig talt refererer til minneceller i koden sin, og skaper mye plass for minnelekkasjer.

Q2. Hva er søppelinnsamling og hva er fordelene med?

Søppelinnsamling er prosessen med å se på haugeminne, identifisere hvilke gjenstander som er i bruk og hvilke som ikke er, og slette ubrukte objekter.

Et objekt i bruk, eller et referert objekt, betyr at en del av programmet ditt fremdeles holder en peker til det objektet. Et ubrukt objekt, eller ikke-referert objekt, refereres ikke lenger til av noen del av programmet ditt. Så minnet som brukes av et objekt uten referanse kan gjenvinnes.

Den største fordelen med søppeloppsamling er at den fjerner byrden med manuell minnetildeling / deallocation fra oss slik at vi kan fokusere på å løse problemet.

Q3. Er det noen ulemper med søppelinnsamling?

Ja. Når søppeloppsamleren kjører, har det en innvirkning på applikasjonens ytelse. Dette er fordi alle andre tråder i applikasjonen må stoppes for å la søppeloppsamlertråden effektivt gjøre sitt arbeid.

Avhengig av kravene til applikasjonen, kan dette være et reelt problem som er uakseptabelt av klienten. Imidlertid kan dette problemet bli sterkt redusert eller til og med eliminert gjennom dyktig optimalisering og søppeloppsamling og bruk av forskjellige GC-algoritmer.

Q4. Hva er betydningen av begrepet "Stopp-verdenen"?

Når tråden til søppeloppsamleren går, stoppes andre tråder, noe som betyr at applikasjonen stoppes et øyeblikk. Dette er analogt med husrengjøring eller røyking der beboere nektes tilgang til prosessen er fullført.

Avhengig av behovene til en applikasjon, kan "stop the world" søppeloppsamling føre til en uakseptabel frysing. Dette er grunnen til at det er viktig å gjøre søppeloppsamler og JVM-optimalisering slik at frysingen du opplever er i det minste akseptabel.

Q5. Hva er stack og heap? Hva lagres i hver av disse minnestrukturene, og hvordan henger de sammen?

Stabelen er en del av minnet som inneholder informasjon om nestede metodeanrop ned til gjeldende posisjon i programmet. Den inneholder også alle lokale variabler og referanser til objekter på dyngen som er definert i nåværende metoder.

Denne strukturen gjør at kjøretiden kan komme tilbake fra metoden og vite adressen den ble kalt fra, og også fjerne alle lokale variabler etter at metoden ble avsluttet. Hver tråd har sin egen stabel.

Haugen er en stor mengde minne beregnet for tildeling av objekter. Når du lager et objekt med ny nøkkelord, blir det tildelt på dyngen. Henvisningen til dette objektet lever imidlertid på bunken.

Q6. Hva er generasjons søppelinnsamling, og hva gjør det til en populær søppelinnsamlingsmetode?

Generasjons søppelinnsamling kan defineres løst som strategien som brukes til søppeloppsamleren der haugen er delt inn i et antall seksjoner kalt generasjoner, som hver vil ha gjenstander i henhold til deres "alder" på haugen.

Hver gang søppeloppsamleren kjører, kalles det første trinnet i prosessen merking. Det er her søppeloppsamleren identifiserer hvilke minnestykker som er i bruk og hvilke som ikke er det. Dette kan være en svært tidkrevende prosess hvis alle objekter i et system må skannes.

Etter hvert som flere og flere gjenstander tildeles, vokser listen over objekter og vokser, noe som fører til lengre og lengre tid for søppeloppsamling. Imidlertid har empirisk analyse av applikasjoner vist at de fleste objekter er kortvarige.

Med generasjons søppelinnsamling, blir objekter gruppert i henhold til deres "alder" når det gjelder hvor mange søppelsamlinger de har overlevd. På denne måten spredte hovedtyngden av arbeidet seg over forskjellige mindre og større innsamlingssykluser.

I dag er nesten alle søppeloppsamlere generasjonsgenerative. Denne strategien er så populær fordi den over tid har vist seg å være den optimale løsningen.

Q7. Beskriv i detalj hvordan generasjons søppelinnsamling fungerer

For å forstå hvordan generasjons søppelinnsamling fungerer, er det viktig å først husk hvordan Java heap er strukturert for å legge til rette for generasjons søppelinnsamling.

Haugen er delt opp i mindre rom eller generasjoner. Disse rommene er Young Generation, Old eller Tenured Generation og Permanent Generation.

De ung generasjon er vert for de fleste av de nyopprettede objektene. En empirisk studie av de fleste applikasjoner viser at flertallet av objektene er kortvarige og derfor snart blir kvalifisert for innsamling. Derfor begynner nye objekter sin reise hit og blir først "promotert" til det gamle generasjonsområdet etter at de har nådd en viss "alder".

Begrepet "alder" i generasjons søppelinnsamling refererer til antall samlesykluser objektet har overlevd.

Det unge generasjonsrommet er videre delt inn i tre rom: et Eden-rom og to overlevende rom som Survivor 1 (s1) og Survivor 2 (s2).

De gamle generasjon er vert for objekter somhar levd i minnet lenger enn en viss “alder”. Objektene som overlevde søppeloppsamling fra den unge generasjonen, blir promotert til dette rommet. Det er generelt større enn den unge generasjonen. Siden det er større i størrelse, er søppeloppsamlingen dyrere og forekommer sjeldnere enn i den unge generasjonen.

De permanent generasjoneller oftere kalt, PermGen, inneholder metadata som kreves av JVM for å beskrive klassene og metodene som brukes i applikasjonen. Den inneholder også strengbassenget for lagring av interne strenger. Den er fylt av JVM ved kjøretid basert på klasser som brukes av applikasjonen. I tillegg kan klasser og metoder for plattformbibliotek lagres her.

Først, eventuelle nye gjenstander tildeles Eden-rommet. Begge overlevelsesrommene begynner å være tomme. Når Eden-rommet fylles ut, utløses en mindre søppeloppsamling. Refererte objekter flyttes til det første overlevende rommet. Objekter uten referanse slettes.

Under den neste mindre GC, skjer det samme med Eden-rommet. Ikke refererte objekter slettes og refererte objekter flyttes til et overlevende rom. I dette tilfellet blir de imidlertid flyttet til det andre overlevende rommet (S2).

I tillegg har gjenstander fra den siste mindre GC i det første overlevende rommet (S1) sin alder inkrementert og flyttes til S2. Når alle gjenlevende gjenstander er flyttet til S2, blir både S1 og Eden-rommet ryddet. På dette punktet inneholder S2 objekter med forskjellige aldre.

Ved neste mindre GC gjentas den samme prosessen. Men denne gangen bytter de overlevende plassene. Refererte objekter flyttes til S1 fra både Eden og S2. Overlevende gjenstander eldes. Eden og S2 er ryddet.

Etter hver mindre søppeloppsamlingssyklus blir alderen på hvert objekt sjekket. De som har nådd en viss vilkårlig alder, for eksempel 8, forfremmes fra den unge generasjonen til den gamle eller fastholdte generasjonen. For alle påfølgende mindre GC-sykluser vil objekter fortsette å promoteres til den gamle generasjonsplassen.

Dette utnytter ganske mye prosessen med søppeloppsamling i den unge generasjonen. Etter hvert vil det bli utført en stor søppelsamling på den gamle generasjonen som rydder opp og komprimerer det rommet. For hver større GC er det flere mindre GC.

Q8. Når blir et objekt kvalifisert for søppelinnsamling? Beskriv hvordan Gc samler et kvalifisert objekt?

Et objekt blir kvalifisert for søppelinnsamling eller GC hvis det ikke kan nås fra noen live tråder eller med noen statiske referanser.

Det enkleste tilfellet med at et objekt blir kvalifisert for søppeloppsamling, er hvis alle referanser er null. Sykliske avhengigheter uten direkte ekstern referanse er også kvalifisert for GC. Så hvis objekt A refererer til objekt B og objekt B refererer til objekt A, og de ikke har noen annen direkte referanse, vil begge objekter A og B være kvalifisert for søppelinnsamling.

Et annet åpenbart tilfelle er når et overordnet objekt er satt til null. Når et kjøkkenobjekt internt refererer til et kjøleskapsobjekt og et vaskeobjekt, og kjøkkenobjektet er satt til null, vil både kjøleskap og vask bli kvalifisert for søppeloppsamling sammen med foreldrenes kjøkken.

Q9. Hvordan utløser du søppelinnsamling fra Java-kode?

Du, som Java-programmerer, kan ikke tvinge søppelinnsamling i Java; det vil bare utløse hvis JVM mener at det trenger en søppelsamling basert på Java-haugestørrelse.

Før du fjerner et objekt fra minnet, påkaller søppeltråden finalize () -metoden for det objektet og gir muligheten til å utføre enhver form for opprydding som kreves. Du kan også påberope deg denne metoden med en objektkode, men det er ingen garanti for at søppeloppsamling vil forekomme når du kaller denne metoden.

I tillegg er det metoder som System.gc () og Runtime.gc () som brukes til å sende forespørsel om søppelinnsamling til JVM, men det er ikke garantert at søppelinnsamling vil skje.

Q10. Hva skjer når det ikke er nok massevis av plass til lagring av nye gjenstander?

Hvis det ikke er noe minne for å lage et nytt objekt i Heap, kaster Java Virtual Machine OutOfMemoryError eller mer spesifiktjava.lang.OutOfMemoryError haugplass.

Q11. Er det mulig å «gjenopplive» et objekt som ble kvalifisert for søppelinnsamling?

Når et objekt blir kvalifisert for søppeloppsamling, må GC kjøre fullføre metode på den. De fullføre metoden er garantert å kjøre bare en gang, og dermed flagger GC objektet som ferdigbehandlet og gir det hvile til neste syklus.

I fullføre metode kan du teknisk "gjenopplive" et objekt, for eksempel ved å tilordne det til en statisk felt. Objektet vil bli levende igjen og ikke kvalifisert for søppeloppsamling, slik at GC ikke vil samle det opp i løpet av neste syklus.

Objektet vil imidlertid bli markert som ferdig, så når det blir kvalifisert igjen, vil ikke finaliseringsmetoden bli kalt. I hovedsak kan du bare snu dette "oppstandelsestriket" en gang i løpet av objektet. Vær oppmerksom på at dette stygge hacket bare skal brukes hvis du virkelig vet hva du gjør - men å forstå dette trikset gir litt innsikt i hvordan GC fungerer.

Q12. Beskriv sterke, svake, myke og fantomreferanser og deres rolle i søppelsamling.

I likhet med at minne administreres i Java, kan en ingeniør trenge å utføre så mye optimalisering som mulig for å minimere ventetid og maksimere gjennomstrømning, i kritiske applikasjoner. Mye som det er umulig å eksplisitt kontrollere når søppeloppsamling utløses i JVM, det er mulig å påvirke hvordan det oppstår med hensyn til objektene vi har skapt.

Java gir oss referanseobjekter for å kontrollere forholdet mellom objektene vi lager og søppeloppsamleren.

Som standard refereres hvert objekt vi oppretter i et Java-program med en variabel:

StringBuilder sb = ny StringBuilder ();

I utdraget ovenfor er ny søkeord oppretter et nytt StringBuilder objekt og lagrer det på dyngen. Variabelen sb lagrer deretter en sterk referanse til dette objektet. Hva dette betyr for søppeloppsamleren er at den spesielle StringBuilder objektet er ikke kvalifisert for innsamling i det hele tatt på grunn av en sterk referanse som det holdes av sb. Historien endres bare når vi opphever sb som dette:

sb = null;

Etter å ha ringt linjen over, vil objektet være kvalifisert for innsamling.

Vi kan endre dette forholdet mellom objektet og søppeloppsamleren ved å eksplisitt pakke det inn i et annet referanseobjekt som ligger inne java.lang.ref pakke.

EN myk referanse kan opprettes til objektet ovenfor slik:

StringBuilder sb = ny StringBuilder (); SoftReference sbRef = ny SoftReference (sb); sb = null;

I utdraget ovenfor har vi opprettet to referanser til StringBuilder gjenstand. Første linje skaper en sterk referansesb og den andre linjen skaper en myk referansesbRef. Den tredje linjen bør gjøre gjenstanden kvalifisert for innsamling, men søppeloppsamleren vil utsette innsamlingen på grunn av sbRef.

Historien vil bare endre seg når minnet blir stramt og JVM er på randen av å kaste en Tomt for minne feil. Med andre ord samles objekter med bare myke referanser som en siste utvei for å gjenopprette minne.

EN svak referanse kan opprettes på en lignende måte ved hjelp av Svak referanse klasse. Når sb er satt til null og StringBuilder objektet bare har en svak referanse, vil JVMs søppeloppsamler absolutt ikke ha noe kompromiss og umiddelbart samle gjenstanden i neste syklus.

EN fantomreferanse ligner en svak referanse, og et objekt med bare fantomreferanser vil bli samlet uten å vente. Fantomreferanser blir imidlertid innhentet så snart gjenstandene deres er samlet. Vi kan avstemme referansekøen for å vite nøyaktig når objektet ble samlet.

Q13. Anta at vi har en sirkulær referanse (to objekter som refererer til hverandre). Kan et slikt par objekter bli kvalifisert for søppeloppsamling, og hvorfor?

Ja, et par gjenstander med en sirkulær referanse kan bli kvalifisert for søppeloppsamling. Dette er på grunn av hvordan Java søppeloppsamler håndterer sirkulære referanser. Den anser objekter som levende ikke når de har noen referanse til dem, men når de kan nås ved å navigere i objektgrafen fra en hvilken som helst søppeloppsamlingsrot (en lokal variabel i en live tråd eller et statisk felt). Hvis et par gjenstander med en sirkulær referanse ikke kan nås fra noen rot, anses det å være kvalifisert for søppeloppsamling.

Q14. Hvordan representeres strenger i minnet?

EN String forekomst i Java er et objekt med to felt: a char [] verdi felt og et int hash felt. De verdi feltet er en rekke tegn som representerer selve strengen og hasj feltet inneholder hashCode av en streng som er initialisert med null, beregnet i løpet av den første hashCode () ringe og bufret helt siden. Som en merkelig edge case, hvis en hashCode av en streng har nullverdi, må den beregnes på nytt hver gang hashCode () er kalt.

Viktig ting er at en String forekomst er uforanderlig: du kan ikke hente eller endre den underliggende røye [] array. Et annet trekk ved strengene er at de statiske konstante strengene lastes og caches i en strengbasseng. Hvis du har flere identiske String objekter i kildekoden din, er de alle representert av en enkelt forekomst ved kjøretid.

Q15. Hva er en strykebygger, og hva er brukstilfellene? Hva er forskjellen mellom å legge en streng til en strengbygger og sammenkoble to strenger med en + -operatør? Hvordan skiller strengbygger seg fra Stringbuffer?

StringBuilder tillater manipulering av tegnsekvenser ved å legge til, slette og sette inn tegn og strenger. Dette er en foranderlig datastruktur, i motsetning til String klasse som er uforanderlig.

Når du sammenkobler to String tilfeller, et nytt objekt opprettes og strengene kopieres. Dette kan føre til en enorm søppeloppsamler overhead hvis vi trenger å lage eller endre en streng i en løkke. StringBuilder tillater håndtering av strengmanipulasjoner mye mer effektivt.

StringBuffer er forskjellig fra StringBuilder ved at den er trådsikker. Hvis du trenger å manipulere en streng i en enkelt tråd, bruk StringBuilder i stedet.

3. Konklusjon

I denne artikkelen har vi dekket noen av de vanligste spørsmålene som ofte vises i Java-ingeniørintervjuer. Spørsmål om minnehåndtering blir stort sett stilt til Senior Java Developer-kandidater, da intervjueren forventer at du har bygget ikke-trivielle applikasjoner som ofte er plaget av minneproblemer.

Dette skal ikke behandles som en uttømmende liste med spørsmål, men heller en startpute for videre forskning. Vi i Baeldung ønsker deg lykke til i kommende intervjuer.

Neste » Java Generics intervjuspørsmål (+ svar) « Tidligere Java 8 intervju spørsmål (+ svar)

$config[zx-auto] not found$config[zx-overlay] not found