de colectare a gunoiului
Cele mai frecvente și complet satisfăcătoare tehnica este numai de colectare a gunoiului automat, sau pur și simplu de colectare a gunoiului.
Mecanismul de colectare a gunoiului
Colectorul de gunoi (colector de gunoi) - este o funcție a sistemului executiv (sistem de execuție) limbaj de programare. Colectorul de gunoi efectuează detectarea și eliminarea obiectelor imposibil de găsit, fără a fi nevoie de a gestiona cererea, deși cererea poate avea la dispoziție diferite mijloace de colector al activității de control.
O examinare detaliată a tuturor problemelor de colectare a gunoiului necesită o carte separată. (La sfârșitul conferinței, a se vedea bibliografia pe această temă.) Să considerăm principiile generale și problemele în curs de dezvoltare, cu accent pe proprietăți care sunt importante pentru dezvoltatorii de software.
un cerințe gunoier
Colectorul de gunoi ar trebui să fie, fără îndoială, corect pentru a satisface două cerințe:
Proprietățile unui colector de gunoi
Bunătatea. fiecare obiect colectat pentru a fi imposibil de atins.
Integralității. fiecare obiect inaccesibil trebuie colectat.
Calitatea - o cerință absolută: este mai bine să nu colecteze gunoiul de a dispune de obiectul dorit. Avem nevoie de încredere deplină că managementul memoriei poate fi de încredere orbește. De fapt, este necesar să se uite despre asta aproape toate, fiind sigur că cineva este într-un fel reduce dezordine în programul tău, precum și pe cineva într-un fel ia departe gunoiul în biroul dumneavoastră atunci când nu sunt, dar nu curat în timp ce cărțile, calculator și de familie fotografii de pe masă.
Integralitatea de dorit - fără ea încă mai puteți rula în problema pe care colectorul de gunoi trebuie să decidă dacă memoria este irosit pe obiecte inutile. Dar nu se poate cere perfectiune: colector poate fi utilă în cazul în care colectează cea mai mare parte de moloz, uneori, sărind peste una sau două obiecte.
Această observație necesită specificații. În practică, orice colector la scară comercială trebuie să fie completă. Integralitatea, în practică, este de asemenea necesară, ca și calitate, dar mai puțin stricte, pentru a parafraza definiția sa: „fiecare obiect imposibil de găsit în cele din urmă trebuie să fie asamblate.“ Să presupunem că putem face procesul de asamblare mai eficient, datorită unui algoritm care colectează fiecare obiect imposibil de găsit, dar poate fi amânată cu referire la unele dintre ele: un astfel de sistem ar fi acceptabil pentru majoritatea aplicațiilor. Această idee a fost discutată în continuare algoritmul „de colectare a gunoiului de generații“, care să fie eficientă, mai scanează zona de memorie care conține obiecte imposibil de găsit sunt mult mai probabil, și mai puțin probabil să acorde o atenție la alte zone de memorie.
Cu un astfel de compromis pentru colectorul de gunoi va trebui să introduceți nu numai criteriile binare de completitudine și de calitate, dar criteriul numit promptitudinea (oportunitatea). Valoarea sa este intervalul de timp din momentul în care obiectul devine imposibil de găsit, până la eliminarea, și este important ca valoarea medie a timpului și limita superioară.
Determinarea calității evidențiază dificultățile asociate cu colectarea gunoiului pentru anumite limbaje de programare, precum și rolurile respective ale limbii și punerea sa în aplicare. De ce, de exemplu, de colectare a gunoiului nu este, de obicei, se aplică C ++? De obicei, citat din motive legate de cultura: în lume, fiecare dezvoltator ar trebui să aibă grijă de „jucării“ lor (conform Stephenson); el pur și simplu nu are încredere în nici un mecanism automat de a gestiona afacerile sale. Dar, dacă acesta ar fi fost motivul real, nu o justificare a posteriori, C ++ mediu ar putea oferi cel puțin de colectare a gunoiului Cum de a conecta o posibilitate, dar cele mai multe implementari nu.
Adevărata problemă constă în structura limbii, dar nu și în tehnologie compilator sau tradiții culturale. C ++, C urmând, liber tipizat; acesta oferă posibilitatea de a converti tipul unui obiect prin care un tip poate fi citate ca esența unui tip diferit. constructie:
Pentru a rezolva această problemă, au fost propuse diferite metode. O gamă largă de aplicații care le-au primit, din cauza restricțiilor impuse. Limbajul Java poate fi privit ca o familie de limbaj C ++, care a introdus restricții semnificative privind tipul de sistem, până la eliminarea moștenirii multiple și universalizare pentru a face în cele din urmă posibile programe de colectare a gunoiului în lume, bazată pe C.
Atunci când sistemul de tip, desigur, posibilitatea de a combina puterea de moștenire multiplă și universalizarea tipurilor de securitate și de sprijin pentru colectarea gunoiului eficient proiectat cu atenție.
Baza de colectare a gunoiului
Luați în considerare activitatea de colector de gunoi.
Așa cum este cazul cu numărarea de referință, facilități includ un câmp suplimentar care este utilizat aici pentru a marca. Dar memoria necesară pentru acest domeniu este nesemnificativ - doar un singur bit pentru fiecare obiect. După cum se va vedea atunci când studiază punerea în aplicare dinamică capacități de legare OO impune ca obiectul are o informație internă suplimentare (de exemplu, tip). Această informație durează de obicei una sau două cuvinte în fiecare obiect. Bit mărci pot face parte din cuvinte oficiale, și nu va ocupa mai mult de memorie.
Construiți pe un „totul sau nimic“
Când trebuie să activați colectorul de gunoi?
colectorii de gunoi clasice sunt activate la cerere și de muncă până la finalizare. Cu alte cuvinte, colectorul de gunoi nu funcționează, este încă memoria aplicației. De îndată ce nu este suficient, aplicația începe un ciclu complet de colectare a gunoiului - o marcă de fază și următoarea fază de curățare.
Această tehnică poate fi descrisă ca fiind „totul sau nimic“. Avantajul său este că acesta nu produce o supraîncărcare până suficientă memorie. În cazul în care programul depășește resursele accesibile, pedeapsa este numit colector de gunoi.
Un astfel de sistem poate fi încă acceptabil pentru aplicații de lot. Dar, aici, la o rată ridicată de memorie virtuală cu suprasarcina reală poate duce la pierderea grave în performanță atunci când sistemul creează un număr mare de obiecte, din care doar o mică parte este în fiecare moment realizabil.
De colectare a gunoiului pe un „totul sau nimic“ nu va funcționa pentru sisteme interactive sau sisteme în timp real. Noi reprezentăm sistemul de avertizare atac cu rachete, care are un interval de 50 milisecunde pentru a răspunde la lansarea rachetei. Să presupunem că programul a funcționat perfect, până când sistemul a trecut dincolo de limitele memoriei, dar, din păcate, acest eveniment a avut loc în momentul lansării rachetei, atunci când, în locul sistemului de operare a început să gunoier pe îndelete.
În astfel de cazuri, problema nu este efectul global al pierderilor de timp asociate cu colectarea gunoiului: o anumită pierdere de productivitate poate fi destul de permis pentru dezvoltatori și utilizatori, ca plată pentru fiabilitate și comoditate furnizate de colectare automată a gunoiului. Dar pierderile temporare ar trebui să fie distribuite în mod egal. exploziile imprevizibile neacceptabile de activitate gunoier. Mai bine de broască țestoasă decât iepure de câmp, din când în când, fără notificare doarme pentru o jumătate de oră. De referință de numărare, dacă nu pentru defect fatală, ar satisface sloganul „mai bine pentru a merge încet, dar la o viteză constantă, cu atât mai repede, dar cu opriri neașteptate și imprevizibile.“
Desigur, pierderea temporară ar trebui să fie nu numai permanentă, ci, de asemenea, mici. În cazul în care cererea nu este de colectare a gunoiului - iepure, nimeni nu va fi de acord să-l înlocuiască cu o broască țestoasă. Colector bun gunoi trebuie să asigure o întârziere de cel mult 5-15%. Deși unii ar spune că acest lucru este inacceptabil și știu destul de câteva aplicații care necesită costuri mai mici. De asemenea, trebuie să ia în considerare faptul că eliminarea manuală este necesară în absența de colectare a gunoiului, și nici o achiziție în jurul fără costuri. În ciuda tuturor costurilor, este nevoie de colectare a gunoiului.
În timpul discuției a relevat două probleme suplimentare, eficiența colectării gunoiului: performanța globală (performanța generală) și modul de pornire-oprire (incrementality).
Avansat (Advanced) abordare de colectare a gunoiului
Un colector bun ar trebui să ofere performanțe bune, lucrând ca o constantă, iar modul de pornire-oprire, devenind acceptabil pentru aplicații interactive, și chiar sisteme în timp real.
Prin urmare, prima cerință - trebuie să permită dezvoltatorilor să gestioneze pornire și cicluri de închidere colector. În special, biblioteca ar trebui să prevadă proceduri:
Apel prima oprire cu bicicleta pentru colectarea gunoiului până la noi; în al doilea rând - colector include restaurarea o stare normală de funcționare; În al treilea rând - a face colector efectua imediat un ciclu complet de funcționare. Să presupunem că un sistem conține o secțiune critică de performanță de timp, care nu ar trebui să fie nici întârzieri imprevizibile. În acest caz, dezvoltatorul poate provoca collection_off la începutul acestei secțiuni și collection_on la capătul său; în orice alt punct în care cererea este inactiv (de exemplu, în timpul intrare sau de ieșire), puteți rula collect_now.
Aplicarea practică a generației de colectare a gunoiului are mai multe variante. În special, obiectele sunt de obicei împărțite nu numai pe tineri și vechi, dar un număr mai mare de generații, cu diferite strategii pentru a construi gunoiul de diferite generații.
Algoritmi de colectare a gunoiului paralel
Pentru o soluție completă pentru problema de lucru în modul de pornire-oprire, selectați colectorul de gunoi singur fir foarte atractiv de executie, desigur, cu condiția ca suport pentru sistemul de operare multi-tasking. Această tehnică este cunoscută sub numele de colectare a gunoiului "on the fly" (on-fly) sau paralel.
În timpul de colectare a gunoiului privind punerea în aplicare a zbura orientat-obiect sistem utilizează două fluxuri separate (de multe ori corespunde la două procese separate sistem de operare): aplicații și colector. Odată ce aplicația alocă obiecte de memorie utilizând liniile directoare stabilite; Numai colector eliberează memoria folosind operații Reclaim.
Colector va rula în mod continuu, repetarea marca de fază și de a urmări curățare fază pentru a detecta și elimina obiecte imposibil de găsit.
fluxuri separate nu sunt neapărat procese separate. Acestea pot fi, pentru a evita costurile suplimentare de comutare între procese sau fire, să aibă corutine plate. (Mai multe coroutine vor fi discutate în capitolul 12 al cursului „Bazele de proiectare orientate-obiect,“ ia în considerare „paralelismul“)
Chiar și așa, de colectare a gunoiului pe zbor, în practică, este productivitatea generală nesatisfăcătoare. Acest lucru este regretabil, pentru că metoda este destul de bun, mai ales în cazul în care utilizarea algoritmului Dijkstra (a se vedea. Referință bibliografică).
Această idee necesită o schimbare în arhitectura hardware dominante și, probabil, este puțin probabil să găsească o aplicație rapidă. Sper că răspunsul la întrebarea este uneori întrebat -
„Ce tip de hardware cele mai potrivite pentru tehnologia de obiect?“ -
primul punct de pe lista de dorințe va fi disponibilitatea unui procesor separat pentru colectarea gunoiului.