CodeGym /Blog Java /Aleatoriu /Mai multe despre gunoiul
John Squirrels
Nivel
San Francisco

Mai multe despre gunoiul

Publicat în grup
Bună! În ultima lecție, ne-am familiarizat mai întâi cu colectorul de gunoi încorporat din Java și ne-am făcut o idee aproximativă despre cum funcționează. Funcționează în fundal în timp ce programul dumneavoastră rulează, colectând obiecte inutile care vor fi șterse ulterior. Astfel, eliberează memorie care poate fi folosită pentru a crea noi obiecte în viitor.
Mai multe despre colectorul de gunoi - 1
În această lecție, vom discuta mai detaliat cum funcționează. De exemplu, cum și când un obiect devine inutil? Și cum află gunoiul? Acestea sunt întrebări la care vom răspunde în timpul lecției de astăzi :) Lecția va fi mai degrabă o prezentare generală: nu trebuie să înveți acest material pe de rost. Intenția este în principal să vă extindeți viziunea cu privire la modul în care funcționează memoria și colectorul de gunoi, așa că doar citiți și găsiți ceva nou pentru dvs. :) Hai să mergem! Primul lucru pe care trebuie să-l rețineți este că colectorul de gunoi funcționează în paralel cu programul dvs. Nu face parte din programul dvs. Funcționează separat (în ultima lecție, am comparat asta cu un robot aspirator) Dar nu a fost întotdeauna așa. Colectarea gunoiului obișnuia să fie efectuată pe același fir ca și programul dvs. La un anumit program (o dată la câteva minute), colectorul de gunoi ar verifica prezența obiectelor nedorite în program. Problema era că programul se bloca (nu se executa) în timpul acestei verificări și colectare a gunoiului. Imaginează-ți că stai în biroul tău la serviciu. Dar apoi intră femeia de curățenie să spele podele. Ea te alungă de la computer timp de 5 minute și tu aștepți până când ea a terminat de curățat. În acest timp, nu poți lucra. Cam așa funcționa colectarea gunoiului :) Acest mecanism a fost schimbat ulterior, iar acum colectorul de gunoi rulează în fundal, nu împiedică activitatea programului în sine. Știți deja că un obiect moare când nu mai are referințe. In realitate,colectorul de gunoi nu numără referințele la obiecte . În primul rând, acest lucru ar putea dura mult timp. În al doilea rând, nu este foarte eficient. La urma urmei, obiectele se pot referi unele la altele! Mai multe despre colectorul de gunoi - 2Figura arată un exemplu în care 3 obiecte se referă unul la celălalt, dar nimeni altcineva nu se referă la ele. Cu alte cuvinte, restul programului nu are nevoie de ele. Dacă gunoiul ar număra pur și simplu referințe, aceste 3 obiecte nu ar fi colectate și memoria nu ar fi eliberată (există referințe la ele!). Putem compara asta cu o navă spațială. În timpul zborului, astronauții decid să verifice lista pieselor de schimb disponibile pentru reparații. Printre altele, ei găsesc un volan și pedale de la o mașină obișnuită. Evident, nu sunt necesare aici și ocupă spațiu inutil (deși aceste două părți sunt legate între ele și au unele funcții). Dar în interiorul navei spațiale, acestea sunt gunoi inutile care ar trebui aruncate. În consecință, în Java, a fost luată decizia de a colecta gunoiul pe baza nu pe baza numărării de referințe,accesibil și inaccesibil . Cum determinăm dacă un obiect este accesibil? Totul este pur și simplu ingenios. Un obiect este accesibil dacă este referit de un alt obiect accesibil. Astfel, obținem un „lanț de accesibilitate”. Pornește când începe programul și continuă pe durata programului. Arată cam așa: Mai multe despre colectorul de gunoi - 3 săgeata din figură indică codul executabil al programului nostru. Codul (de exemplu, main()metoda) creează referințe la obiecte. Aceste obiecte se pot referi la alte obiecte, acele obiecte la altele și așa mai departe. Acesta formează un lanț de referință. Dacă puteți urmări până la lanț de la un obiect la „referința rădăcină” (cea creată direct în cod executabil), atunci este considerat accesibil. Astfel de obiecte sunt marcate cu negru în imagine. Dar un obiect este inaccesibil dacă obiectul iese din acest lanț, adică niciuna dintre variabilele din codul în curs de executare nu face referire la el și nu poate fi atins prin „lanțul de referință”. În programul nostru, două astfel de obiecte sunt marcate cu roșu. Rețineți că aceste obiecte „roșii” au referințe unele la altele. Dar, așa cum am spus mai devreme, colectorul de gunoi modern al Java nu numără referințele. Acesta determină dacă un obiect este accesibil sau inaccesibil. Ca urmare, se va apuca de cele două obiecte roșii din figură. Acum să ne uităm la întregul proces de la început până la sfârșit. Procedând astfel, vom vedea, de asemenea, cum este aranjată memoria în Java :) Toate obiectele Java sunt stocate într-o zonă specială de memorie numită heap . În limbajul de zi cu zi, o grămadă este de obicei un munte de articole, în care totul este amestecat. Dar nu asta este heap-ul în Java. Structura sa este foarte logică și rezonabilă. La un moment dat, programatorii Java au descoperit că toate obiectele lor puteau fi împărțite în două tipuri: obiecte simple și „obiecte cu viață lungă”. „Obiectele cu viață lungă” sunt obiecte care au supraviețuit multor runde de colectare a gunoiului. De obicei trăiesc până la sfârșitul programului. În cele din urmă, grămada plină, în care sunt stocate toate obiectele, a fost împărțită în mai multe părți. Prima parte are un nume frumos: eden(din biblica „Grădina Edenului”). Acest nume se potrivește, deoarece aici ajung obiectele după ce sunt create. Aceasta este partea din memorie în care sunt create obiecte noi când folosim cuvântul cheie new. Pot fi create o mulțime de obiecte. Când această zonă rămâne fără spațiu, începe o colectare inițială „rapidă” a gunoiului. Trebuie să spunem că gunoiul este foarte deștept. Alege un algoritm în funcție de faptul dacă heap-ul are mai mult gunoi sau mai multe obiecte vii. Dacă aproape toate obiectele sunt gunoi, colectorul marchează obiectele vii și le mută într-o altă zonă de memorie. Apoi zona actuală este complet curățată. Dacă nu există mult gunoi, iar grămada este în mare parte obiecte vii, colectorul marchează gunoiul, îl curăță și împachetează celelalte obiecte. noi am spus "un spațiu de supraviețuire . Un spațiu de supraviețuire , la rândul său, este împărțit în generații . Fiecare obiect aparține unei anumite generații, în funcție de câte runde de colectare a gunoiului a supraviețuit. Dacă un obiect a supraviețuit unei runde de colectare a gunoiului, atunci este în „Generația 1”; dacă 5, atunci „Generația 5”. Împreună, Edenul și un spațiu de supraviețuire formează o zonă numită generația tânără . Pe lângă generația tânără, grămada are o altă zonă de memorie numită generația veche. Tocmai aceasta este zona în care ajung obiectele cu viață lungă care au supraviețuit multor runde de colectare a gunoiului. Există avantaje de a le menține separate de toate celelalte. Colectarea completă a gunoiului se realizează numai atunci când vechea generație este plină, adică există atât de multe obiecte cu viață lungă în program încât nu există suficientă memorie. Acest proces implică mai mult de o zonă de memorie. În general, implică toate obiectele create de mașina Java. Desigur, acest lucru necesită mult mai mult timp și resurse. Tocmai aceasta este decizia luată de a depozita separat obiectele cu viață lungă. „Colectarea rapidă a gunoiului” se realizează atunci când alte zone rămân fără spațiu. Aceasta implică o singură zonă, ceea ce o face mai rapidă și mai eficientă. În cele din urmă, când chiar și zona pentru obiecte cu viață lungă este complet umplută, colectarea completă a gunoiului este declanșată. Astfel, colectorul folosește cea mai „grea” unealtă doar atunci când este imposibil de evitat. Iată o reprezentare vizuală a structurii heap și a colecției de gunoi: Mai multe despre colectorul de gunoi - 4
Comentarii
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION