Colectarea gunoiului 1

În programare, de colectare a gunoiului [1] (de colectare a gunoiului născut.) - o formă de management automat al memoriei. Un proces special numit colector de gunoi (Ing. Colector de gunoi), eliberează periodic de memorie prin eliminarea obiectelor care nu mai sunt în aplicații de cerere.

Dacă memoria calculatorului a fost fără sfârșit. s-ar putea pur și simplu lăsați obiecte nedorite în memorie. De colectare a gunoiului - emulare a PC-ului în memoria de capăt fără sfârșit [2]. Multe restricții de gunoi de colecție (nu există nici o garanție că finalizer este executat, controlează numai memoria, dar nu si alte resurse) sunt derivate din această metaforă.

De colectare a gunoiului a fost folosit pentru prima dată în 1959 Dzhonom Makkarti mediu de programare dezvoltat pe lor limbaj funcțional de programare Lisp. Mai târziu a fost folosit în alte, în principal, sisteme și limbaje de programare - în funcționale și logice. Nevoia de colectare a gunoiului în limbile acestor tipuri, datorită faptului că structura acestor limbi face foarte inconfortabil de urmărire durata de viață a obiectelor în memorie și gestionarea manuală a acesteia. Utilizat pe scară largă în aceste limbi și liste bazate pe aceste structuri de date complexe, în timp ce programele sunt în mod constant create, sunt construite, extinse, copiate, și de a determina corect momentul scoaterii unui obiect dificil.

probleme de memorie manuale

Metoda tradițională de gestionare a memoriei limba politică este manual. Esența ei în următoarele:

  • Pentru a crea un obiect pe programator heap solicită în mod explicit comanda de alocare de memorie. Această comandă returnează un pointer la zona de memorie alocată, care este stocat și utilizat pentru a accesa.
  • Atâta timp cât este necesar pentru programul de obiectul creat, programul îl accesează printr-un pointer salvat anterior.
  • Atunci când nici un obiect trece, programatorul face apel în mod explicit comanda deallocation, care trece un pointer la un obiect șters.

În orice limbă, permite crearea de obiecte pe heap, eventual două probleme posibile: referințe atârnate și pierderi de memorie.

Mecanismul de colectare a gunoiului

principii de bază

De colectare a gunoiului - o tehnologie care permite, pe de o parte, pentru a simplifica programarea, salvarea programator de la a trebui să ștergeți manual obiectele create pe heap, cu o alta - pentru a elimina erorile cauzate de gestionare incorectă de memorie manuală.

Sistemul de memorie liberă taxe de colectare a gunoiului de obiecte care nu mai sunt utilizate, este atribuit mediului de execuție a programului. Programatorul creează un obiect dinamic și le utilizează, el nu poate avea grijă de îndepărtarea obiectului, așa cum o face pentru el miercuri. Pentru punerea în aplicare a colectării gunoiului în mediul de execuție include un modul software special numit „colector de gunoi.“ Acest modul se execută periodic determină care dintre creatului nu mai sunt utilizate în grămada de obiecte și eliberează memoria ocupată de acestea.

GC frecvența de start este determinată de caracteristici ale sistemului. Colector poate rula în fundal, pornind de la un program atunci când inactiv (de exemplu, atunci când programul este inactiv, de așteptare pentru intrare de utilizator). Colectorul de gunoi ruleaza întrerupe definitiv activitatea lor pe timp de executie a programului atunci când următoarea operație de alocare de memorie este imposibil de realizat datorită faptului că toată memoria disponibilă este epuizată. După eliberarea de memorie pentru a întrerupe funcționarea alocare de memorie este reluată, iar programul continuă să funcționeze pe. Dacă se dovedește că este imposibil să se elibereze memoria, runtime oprește programul cu un mesaj de eroare „Nu există memorie suficientă“.

obiecte de atins

Deși, în general, este imposibil să se determine cu exactitate când obiectul a fost utilizat pentru ultima dată și nu mai este nevoie, colectorii de gunoi folosesc estimări conservatoare pentru determinarea că obiectul în viitor este garantat să nu fie utilizat.

În mod normal, criteriul că obiectul este încă în uz, este de a avea legături cu ea. Dacă nu există mai multe referiri la obiect, în mod evident, acesta nu poate fi folosit de program, și, prin urmare, pot fi șterse. Acest criteriu este folosit de cele mai multe colectoare moderne gunoi numite obiecte mai accesibile.

Informal, puteți specifica următoarea definiție recursiv obiect realizabil:

O astfel de definiție nu este, teoretic, precum și în numărul de realizabile, în conformitate cu el, există, de asemenea, obiecte care nu vor fi utilizate, dar care încă există link-uri. Optimul ar fi considerat un obiect imposibil de atins, care, în cursul programului suplimentar de lucru nu va fi un singur tratament, dar identificarea unor astfel de site-uri nu este posibil, deoarece a redus la problema indecidabila pentru a opri (este suficient să presupunem că un obiect X va fi utilizat dacă și numai în acest caz, în cazul în care programul este de succes P).

Algoritmul prezintă steaguri

Un algoritm simplu pentru determinarea obiectelor accesibil „, marchează algoritmul» (Marcu și Sweep), este după cum urmează:

Algoritmul de numărare de referință

O altă variantă a algoritmului pentru determinarea accesibilități - de obicei numărare de referință. Utilizarea sa retardati operațiunile de atribuire de link-uri, dar definiția obiectelor accesibil este banal - toate obiectele, valoarea de referință conta mai mare decât zero. Fără elaborare suplimentară, acest algoritm, spre deosebire de cel anterior, nu se elimina lanțurile ciclic închise de obiecte învechite, păstrează o trimitere la unul pe altul.

Strategia de colectare a gunoiului

Odată ce se determină setul de obiecte de neatins, colectorul de gunoi poate recupera memoria ocupată de ei, și se lasă restul așa cum este. Puteți posta, de asemenea, de memorie liber pentru a muta toate sau o parte din restul obiectelor din alte zone de memorie, actualizarea în același timp, toate referirile la ele. Aceste două exemple de realizare sunt denumite, respectiv, și pentru a muta nedeplasabili.

Ambele strategii au atât avantaje și dezavantaje

Viteza de eliberare și eliberare de memorie colector de gunoi imobilă va elibera memoria (deoarece această operațiune duce la marcarea blocul de memorie corespunzător ca liber), dar își petrece mai mult timp cu privire la selectarea ei (deoarece memoria este segmentat, iar alocarea este necesară pentru a găsi în memorie cantitatea dorită de o dimensiune bloc adecvat) . Mutarea colector necesită relativ mai mult timp de colectare a gunoiului (petrecut timp suplimentar pe defragmentare de memorie și schimba toate referințele la obiectele plutitoare), dar mișcarea permite extrem de simplu și rapid (Despre (1)), algoritmul de alocare a memoriei. Atunci când obiectele sunt mutate de defragmentare, astfel încât să se separe toată memoria în două zone mari - ocupate și neocupate, și stochează un pointer la granița lor. Pentru a evidenția noua memorie trebuie să se deplaseze numai frontiera, revenind piesa de la începutul de memorie liberă. Viteza de acces la obiecte în obiectele heap, câmpurile care sunt utilizate împreună, se deplasează colector permite introducerea în memorie aproape unul de altul. Apoi, ele sunt susceptibile de a fi în cache-ul procesorului, în același timp, ceea ce va reduce numărul de apeluri într-o memorie RAM relativ lent. Compatibil cu un cod străin mutarea gunoier cauzează dificultăți atunci când utilizați cod care nu este controlat de un sistem automat de management al memoriei (un astfel de cod se numește străină (engleză. Statele de externe), în terminologia tradițională sau negestionate (Ing. Negestionate the) în terminologia Microsoft). Un pointer la memoria alocată sistemului cu colector neclintiți, puteți transfera pur și simplu codul străin care urmează să fie utilizat ținând cel puțin un obiect de referință normal la colectorul de a nu-l șters. Mută ​​selectorul schimbă poziția obiectelor în memorie, schimbarea sincronă toate referirile la ele, ci pentru a schimba referinta nu se poate într-un cod străin, ca rezultat al codului transmis de link-urile străine după mutarea obiect va deveni invalid. Pentru a lucra cu un cod străin folosit o varietate de tehnici speciale, de exemplu, fixarea - obiect de blocare explicită, care interzice deplasarea în timpul colectării gunoiului.

instalațiile de generare

După cum arată practica, nou create obiecte din ce în ce nu pot fi atinse decât obiectele existente pentru o lungă perioadă de timp. Conform acestei legi, mulți colecționari moderne de gunoi sunt împărțite toate obiectele pentru câteva generații - o serie de obiecte cu o durată de viață de aproape. De îndată ce memoria alocată uneia dintre generații, se termină în această generație și în toate obiectele imposibil de găsit mai „tânăr“ este căutat. Toate acestea sunt eliminate, iar restul transferat la generația „mai în vârstă“.

Folosind generațiile reduce ciclul de colectare a gunoiului, reducerea numărului văzut în ansamblul de obiecte, dar această metodă necesită link-urile de urmărire a rulării între generații.

alte mecanisme

obiecte imuabile (Eng. obiecte invariabile) De exemplu, java.lang.String în Java. De îndată ce linia a fost dat un sens, aceasta nu poate fi schimbată. Rutinele va trece link-ul de pe această linie reciproc, iar când toate link-urile vor dispărea, șirul va fi distrus de către colector de gunoi. Finalizers finalizer specifică ce să facă atunci când un obiect cade sub colectorul de gunoi. finalizers De obicei, pentru a scrie învelișurile pe obiecte ale sistemului de operare (fișiere, socluri de rețea.); Ei închid automat obiectul corespunzător. Având în vedere că obiectul este de a colecta poate fi „agățate pentru“ în memorie pentru o lungă perioadă de timp, un bun stil de programare - pentru a închide un fișier sau o priză manual de către o echipă de aproape cum ar fi ().

Cerințe de limbă și sistem

Deci, programul poate folosi de colectare a gunoiului, este necesar să se îndeplinească o serie de condiții referitoare la runtime limbă și cele mai multe sarcini.

Contrar afirmațiilor frecvente, existența gunoier nu scutește programator de la toate problemele de gestionare a memoriei.

Avantaje și dezavantaje

Comparativ cu managementul memoriei manual, de colectare a gunoiului mai sigur, deoarece previne apariția unor pierderi de memorie și link-uri suspendate din cauza îndepărtării prematură a obiectelor. Un alt lucru pozitiv - simplificarea procesului de programare. Pe de altă parte, prezența de colectare a gunoiului poate provoca un dezvoltator fals sentiment lipsit de experiență de securitate, bazată pe ideea că alocarea de memorie liberă și nu trebuie să acorde o atenție, deoarece acestea sunt adresate de către colectorul de gunoi.

De exemplu, obiectul nu va fi șters dacă a rămas cel puțin un indicator neobnulonny în domeniul de aplicare la nivel mondial, și căutarea unui psevdoutechki în limbi de colectare a gunoiului este deosebit de complex. Programatorul nu poate ignora complet problema de gestionare a memoriei, în prezența unui colector de gunoi, deși costurile forței de muncă manuală pentru gestionarea memoriei, în acest caz, este încă semnificativ mai mică decât în ​​alte limbi, cu control manual complet (fără colector și avtodestruktorov). De multe ori critic nu este numai garanția de eliberare a resursei, dar, de asemenea, o garanție că este liber să apeleze orice alte proceduri - de exemplu, fișierele deschise, care intră în secțiunea critică. Dă gestionarea acestor resurse colectorul de gunoi nu poate, deci va trebui să le eliminați manual. Cu toate acestea, în ultimii ani, chiar și în limbi străine cu de colectare a gunoiului introdus abilitatea de a crea clase cu deterministe-metoda de asteptare speciala „destructor» (Evacuați) la ieșirea din zona de vizibilitate.

În multe cazuri, cu sisteme de colectare a gunoiului prezintă eficiență mai mică, atât în ​​viteză și în utilizarea memoriei (care este inevitabilă, deoarece colectorul de gunoi în sine consumă resurse și necesită unele exces de memorie liberă pentru funcționarea normală). În plus, cu sistem de colectare a gunoiului este algoritmi complecși de nivel scăzut sunt puse în aplicare, care au nevoie de acces direct la memoria calculatorului ca utilizarea liberă a indicii nu este posibilă, iar accesul direct la memorie necesită existența unor interfețe speciale scrise în limbaje de nivel scăzut. Pe de altă parte, în sistemele moderne, cu alocarea de operațiuni de colectare a gunoiului de memorie este redusă la elementar adăugarea unitate la sfârșitul gramada. Și o grămadă din timp în timp este compactat prin reducerea fragmentării datelor.

Suport în unele limbi imperative apela în mod automat destructor (C ++ [3]. Iad. Delphi), precum și mai simplu decât de colectare a gunoiului, utilizarea tehnologiei „link-uri inteligente“ (urmărirea numărului de trimiteri la un obiect direct în ea și ștergerea automată atunci când ștergeți ultima referință așa cum se face în tehnologia COM) reduce semnificativ riscul de scurgeri de informații, care să permită concentrate locuri periculoase din clasa de punere în aplicare, fără a necesita resurse suplimentare, în timp ce în același timp, necesită mai mult de calificare de programator. Desigur, pentru a scrie resurse numărul scutit vor avea în continuare, dar destructori automate va da încredere că codul este obligat de a provoca. Cu toate acestea, pentru cele mai frecvent utilizate resurse în toate limbile populare care acceptă avtodestruktory au deja ambalaje automate, care sunt ele însele închid resursa, ținând astfel grija de resurse devine aproape mai ușor decât cu un colector de gunoi imprevizibil.

conveniență semnificative de colectare a gunoiului se produce atunci când obiectele create dinamic trăi o lungă perioadă de timp, în mod repetat, duplicat, iar referirile la acestea sunt transferate între diferitele părți ale programului. Astfel de programe sunt în general destul de dificil să se determine cu exactitate locația în care obiectul nu mai este utilizat și pot fi eliminate. Deoarece este o astfel de situație, atunci când utilizarea pe scară largă a modifică în mod dinamic structuri de date (liste, arbori, grafice), colectarea gunoiului este necesară utilizarea pe scară largă astfel de structuri sunt limbaje funcționale și logice, cum ar fi Haskell. LISP sau Prolog. Utilizarea de colectare a gunoiului în limbile tradiționale imperative (bazată pe paradigma structurală, obiect, probabil augmentată înseamnă) determinat de raportul dorit între simplitatea și viteza de programare și eficiența punerii sale în aplicare.

de gestionare a memoriei în limbi și sisteme specifice

De colectare a gunoiului este adesea în contrast cu managementul memoriei manuală, în care programatorul specifică în mod explicit, atunci când și ce zone de memorie ar trebui să fie eliberat. Cu toate acestea, există limbi în care folosește o combinație a celor două tehnici de gestionare a memoriei, precum și mai există și alte tehnologii pentru a rezolva aceeași problemă fundamentală (de exemplu, EN: regiune inferență).

Unele limbaje de programare necesită utilizarea mecanismului de colectare a gunoiului, în conformitate cu specificația sa (Java C # Eiffel ..), celălalt - din motive de eficiență a punerii în aplicare (de exemplu, limbaje formale pentru calculul lambda) - Aceste limbi sunt numite limbi străine cu colectarea gunoiului. Multe limbi străine cu colectarea gunoiului nu au oportunități pentru îndepărtarea explicită manuală a obiectelor (de exemplu, operatorul delete), prin apariția atârnând referințe excluse, în principiu, iar colectorul de gunoi se ocupă doar cu eliminarea de obiecte care nu sunt referite din program.

Unele limbi (de exemplu, Modula-3) puteți utiliza gestionarea memoriei ca manuală și colectarea gunoiului într-o singură aplicație - folosind două grămezi separate.

articole similare