CodeGym /Java-blogg /Tilfeldig /Mer om søppelsamleren
John Squirrels
Nivå
San Francisco

Mer om søppelsamleren

Publisert i gruppen
Hei! I siste leksjon ble vi først kjent med Javas innebygde søppeloppsamler og fikk en grov ide om hvordan den fungerer. Det fungerer i bakgrunnen mens programmet kjører, og samler inn unødvendige objekter som vil bli slettet senere. Dermed frigjør det minne som kan brukes til å lage nye objekter i fremtiden.
Mer om søppelsamleren - 1
I denne leksjonen vil vi diskutere mer detaljert hvordan det fungerer. For eksempel, hvordan og når blir en gjenstand unødvendig? Og hvordan finner søppelsamleren ut av det? Dette er spørsmål vi skal svare på i løpet av dagens leksjon :) Leksjonen vil være mer som en oversikt: du trenger ikke lære dette materialet utenat. Hensikten er hovedsakelig å utvide din visjon angående hvordan hukommelsen og søppelsamleren fungerer, så det er bare å lese gjennom og finne noe nytt for deg selv :) La oss gå! Det første du må huske er at søppelsamleren jobber parallelt med programmet ditt. Det er ikke en del av programmet ditt. Den kjører separat (i forrige leksjon sammenlignet vi dette med en robotstøvsuger) Men det var ikke alltid slik. Søppelinnsamling ble tidligere utført på samme tråd som programmet ditt. På en tidsplan (en gang med noen få minutter), ville søppelsamleren sjekke for tilstedeværelsen av uønskede objekter i programmet. Problemet var at programmet ville henge (ikke kjøre) under denne sjekken og søppelinnsamlingen. Tenk deg at du sitter på kontoret på jobben. Men så kommer vaskekonen inn for å vaske gulvene. Hun kjører deg bort fra datamaskinen i 5 minutter, og du venter til hun er ferdig med å rydde. I løpet av denne tiden kan du ikke jobbe. Det er omtrent slik søppeloppsamling fungerte :) Denne mekanismen ble senere endret, og nå kjører søppelsamleren i bakgrunnen, ikke hindre arbeidet med selve programmet. Du vet allerede at et objekt dør når det ikke lenger har referanser. I virkeligheten,søppelsamleren teller ikke objektreferanser . For det første kan dette ta lang tid. For det andre er det ikke veldig effektivt. Tross alt kan objekter referere til hverandre! Mer om søppelsamleren - 2Figuren viser et eksempel hvor 3 objekter refererer til hverandre, men ingen andre refererer til dem. Med andre ord, resten av programmet trenger dem ikke. Hvis søppelsamleren bare telte referanser, ville disse 3 objektene ikke blitt samlet og minnet ville ikke bli frigjort (det er referanser til dem!). Vi kan sammenligne dette med et romfartøy. Under flyturen bestemmer astronautene seg for å sjekke listen over reservedeler som er tilgjengelige for reparasjoner. De finner blant annet ratt og pedaler fra en vanlig bil. Åpenbart er de ikke nødvendige her og tar opp plass unødvendig (selv om disse to delene er relatert til hverandre og har noen funksjoner). Men inne i romfartøyet er de ubrukelig søppel som bør kastes. Følgelig, i Java, ble beslutningen tatt om å samle søppel basert ikke på referansetelling,tilgjengelig og utilgjengelig . Hvordan avgjør vi om et objekt er tilgjengelig? Det hele er rett og slett genialt. Et objekt er tilgjengelig hvis det refereres til av et annet tilgjengelig objekt. Dermed får vi en «chain of reachability». Den starter når programmet starter og fortsetter så lenge programmet varer. Det ser omtrent slik ut: Mer om søppelsamleren - 3 Pilen i figuren indikerer programmets kjørbare kode. Koden (for eksempel metoden main()) lager referanser til objekter. Disse objektene kan referere til andre objekter, disse objektene til atter andre, og så videre. Dette danner en referansekjede. Hvis du kan spore langs til kjede fra et objekt til "rotreferansen" (den som er opprettet direkte i kjørbar kode), så anses den som tilgjengelig. Slike gjenstander er merket med svart på bildet. Men et objekt er ikke tilgjengelig hvis objektet faller ut av denne kjeden, dvs. at ingen av variablene i koden som kjøres for øyeblikket refererer til det, og det kan ikke nås gjennom "referansekjeden". I vårt program er to slike objekter merket rødt. Merk at disse "røde" objektene har referanser til hverandre. Men som vi sa tidligere, teller ikke Javas moderne søppelsamler referanser. Den avgjør om et objekt er tilgjengelig eller ikke tilgjengelig. Som et resultat vil den gripe de to røde gjenstandene i figuren. La oss nå se på hele prosessen fra begynnelse til slutt. Ved å gjøre det, vil vi også se hvordan minnet er ordnet i Java :) Alle Java-objekter er lagret i et spesielt minneområde kalt heap . I hverdagsspråket er en haug vanligvis et fjell av gjenstander, hvor alt er blandet. Men det er ikke det haugen er i Java. Strukturen er veldig logisk og rimelig. På et tidspunkt fant Java-programmerere ut at alle objektene deres kunne deles inn i to typer: enkle objekter og "objekter med lang levetid". «Langlivede gjenstander» er gjenstander som har overlevd mange runder med søppelhenting. De lever vanligvis til programmet slutter. Til slutt ble hele haugen, der alle gjenstander er lagret, delt i flere deler. Den første delen har et vakkert navn: eden(fra den bibelske "Edens hage"). Dette navnet er passende, fordi det er her objekter havner etter at de er opprettet. Dette er den delen av minnet hvor nye objekter blir til når vi bruker nøkkelordet ny. Mange objekter kan lages. Når dette området går tom for plass, starter en innledende "rask" søppelinnsamling. Vi må si at søppelsamleren er veldig flink. Den velger en algoritme basert på om haugen har mer søppel eller flere levende objekter. Hvis nesten alle gjenstandene er søppel, merker samleren de levende gjenstandene og flytter dem til et annet minneområde. Da er det nåværende området helt ryddet. Hvis det ikke er mye søppel, og haugen er for det meste levende gjenstander, merker samleren søppelet, rydder det og pakker de andre gjenstandene sammen. Vi sa "et overlevelsesrom . Et overlevelsesrom er på sin side delt inn i generasjoner . Hver gjenstand tilhører en bestemt generasjon, avhengig av hvor mange runder med søppelsamling den har overlevd. Hvis en gjenstand har overlevd én runde med søppelinnsamling, så er den i "Generasjon 1"; hvis 5, så "Generasjon 5". Sammen danner eden og et overlevelsesrom et område som kalles den unge generasjonen . I tillegg til den unge generasjonen har haugen et annet minneområde kalt den gamle generasjonen. Det er nettopp dette området hvor langlivede gjenstander som har overlevd mange runder med søppelhenting havner. Det er fordeler med å holde dem adskilt fra alle de andre. Full søppelhenting utføres først når den gamle generasjonen er full, dvs. det er så mange langlivede objekter i programmet at det ikke er nok minne. Denne prosessen involverer mer enn ett minneområde. Generelt involverer det alle objektene som er opprettet av Java-maskinen. Naturligvis tar dette mye mer tid og ressurser. Dette er nettopp beslutningen ble tatt for å lagre langlivede gjenstander separat. «Rask søppelhenting» gjennomføres når andre områder går tom for plass. Dette involverer kun ett område, noe som gjør det raskere og mer effektivt. Til slutt, når selv området for gjenstander med lang levetid er helt fylt, full søppelhenting utløses. Dermed bruker samleren det "tyngste" verktøyet bare når det er umulig å unngå det. Her er en visuell representasjon av haugstrukturen og søppelsamlingen: Mer om søppelsamleren - 4
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION