Heap este folosit pentru a stoca valori, care pot necesita acces din timpul alocat acestora în memorie și programul este finalizat. Nu există nici un mecanism de limbaj similar la ieșirea din blocul sau funcția pe care se va face zona de memorie nu este disponibilă. La prima vedere, schema de distribuție pentru o astfel de memorie trebuie să aloce memorie de la un capăt al spațiului liniar la altul, până când memoria liberă este distribuit complet. Poate părea că acest lucru este nici o problemă cu redistribuirea sau folosirea excesivă a memoriei ar trebui să apară. În același timp, această abordare are un dezavantaj major, și anume, după prima alocare a memoriei utilizare completă a instrucțiunii următoare, de exemplu,
care va încerca să evidențieze cele patru biți de memorie și returnează un pointer la această zonă va provoca o eroare în program. Cu toate acestea, înainte de a te-a pus cu ea, ar trebui să ne amintim că zona de memorie poate deveni inaccesibile din cauza un astfel de program de activitate, ca o măsură de mutare indicii, etc. De exemplu, spațiul alocat anterior poate deveni indisponibil pentru un șir de variabile, după următoarea alocare:
În același timp, această operație permite accesul la spațiul în cauză a unei alte variabile. Luați în considerare rezultatul misiunii
între cele de mai sus doi operatori. Având în vedere că alți operatori asociați cu datele nu sunt disponibile, astfel de acțiuni vor conduce la faptul că o variabilă va fi disponibil spațiu stringl declarație malloc alocat.
Deoarece, în general, nu este cunoscut la momentul compilării, ca programul este executat, este imposibil să știe la momentul compilării, atunci când devine disponibilă memoria alocată de declarația malloc. Acest lucru înseamnă că, codul este de a restabili o grămadă de câmp nu poate fi generat la momentul compilării, dar pot deveni inaccesibile zone mari alocate pe movila. O modalitate de a depăși această dificultate constă în faptul că programatori (pe baza cunoștințelor lor de modul în care programul va fi realizat) pentru a anticipa momentul în care memoria heap devine indisponibil, și injectat în codul sursă de instrucțiuni explicite pentru realocare. De exemplu, în C pentru eliberarea zonei de memorie alocată variabila: șir, puteți scrie următoarele:
În același timp, această abordare necesită programator mare profesionalism si responsabilitate. Deci, orice metode automate de memorie liberă pentru a utiliza nedorite. În Java, se presupune că responsabilitatea pentru eliberarea memoriei disponibile ar trebui să fie suportate de punerea în aplicare Java în loc de programator; astfel încât orice implementare Java trebuie să aibă mecanisme adecvate. Este demn de remarcat faptul că, în contrast cu modelele de memorie descrise anterior, Java păstrează matrice heap. Toate obektytakzhe stocate pe movila.
Există două posibile grămadă metoda de control în legătură cu restaurarea zonelor inaccesibile de memorie:
• de colectare a gunoiului (colectarea gunoiului);
• Utilizarea numărului de referință (utilizarea de contoare de referință). Prima metodă este, probabil, mai popular, dar, de asemenea, mai este necesar. Avantajul acestei abordări constă în faptul că, înainte de distribuirea completă a spațiului de memorie disponibil nu este necesară pentru restaurarea oricărei părți a acesteia. Ca urmare, în multe cazuri, pentru colectarea gunoiului de timp este, în general, nu este necesar. Dacă (și când) este în continuare necesar de colectare a gunoiului, acest proces are loc în două etape:
• faza de marcare, în care (prin introducerea valorilor în harta de biți) este marcată memoria heap disponibilă pentru variabilele de program.
• faza de compresie, în care spațiul disponibil este mutat la un capăt al grămezii, iar memoria pentru a fi reutilizate, formează un bloc contiguu la celălalt capăt al grămezii. În același timp, desigur, ar trebui să fie verificate cu atenție pentru a schimba în mod corespunzător toate indicii.
Dintre aceste două faze de faza de marcare și permite cele mai interesante modalități alternative de a pune în aplicare mai puțin. Este nevoie de unele mijloace de „etichetare“ a celulelor de memorie, care se pot accesa variabilele programului, dacă este necesar. Aceasta poate fi utilizată o hartă de biți cu o comparație număr suficient bitovdlya cu fiecare celulă a grămezii. Bitmap nu face parte din gramada, și este separat de ea. Fiecare bit din bitmap poate lua una din două valori:
0 - corespunzătoare celulei de memorie nu este disponibilă pentru variabilele de program.
1 - celula de memorie corespunzătoare este disponibilă pentru variabilele programului. B începutul procesului de colectare a gunoiului, toate elementele bitmap sunt setate la 0, iar în performanța algoritmului diferitelor elemente ale cardului este setat la 1. La sfârșitul colectării gunoiului valoarea 1 va avea toate elementele unui bitmap, care corespund celulelor de memorie care sunt disponibile pentru variabilele de program.
Algoritmul simplu de colectare a gunoiului utilizează o stivă (numit un teanc de colectare a gunoiului) și este după cum urmează:
1. Stiva timpul de execuție liniar văzut, până când se găsește o variabilă care indică gramada de celule nemarcată. Acest lucru poate fi fie variabila reală, care este un pointer (un buchet) sau o componentă de înregistrare, care este un pointer. În viitor, toate gramada de celule, moment în care aceste variabile markiruyutsyaposredstvom care încorporează părțile relevante din harta de biți.
4. Al treilea pas se repetă atâta timp cât stiva este liber de colectare a gunoiului, și toate indicii din stiva de execuție vor fi procesate în modul descris.
Ca al treilea pas este întotdeauna etichetat celule nemarcați, apoi, în final, algoritmul se oprește.
Algoritmul descris mai sus este o clară, ușor de înțeles și eficient. Cu toate acestea, ea are un dezavantaj - este nerealist, deoarece necesită utilizarea arbitrară de memorie mărimea stack-ului la momentul sarcinii maxime. Cu alte cuvinte, de colectare a gunoiului vor pur și simplu să nu fi inițiat! Desigur, nimeni nu se așteaptă ca de curățare de memorie va fi efectuată în absența unui spațiu pentru a lucra. În același timp, ca și nevoia de colectare a gunoiului este de memorie mic (și celebru), atunci când memoria este redusă, poate fi inițiată în primul rând. De fapt, există un algoritm de colectare a gunoiului cu cereri de spații de lucru extrem de mici:
1. celula morman Mark, care indică în mod clar valoarea stivei de execuție.
În plus față de spațiul necesar pentru algoritmul bitmap necesită, de asemenea, trei variabile care reprezintă:
• o celulă căreia îi este adresată o cerere;
În același timp, în ceea ce privește timpul de călătorie, algoritmul poate fi extrem de ineficient. În special, acest lucru poate fi cazul atunci când mormanul conține o mulțime de indicii spate, iar acest lucru este prețul pentru care nu utilizează stiva.
Un compromis între cei doi algoritmi vor fi descrise algoritmul lipit Strategia 1 pentru suficientă memorie și strategii de 2 - în caz contrar. De exemplu, în cazul în care stiva este destul de mare, algoritmul poate fi utilizat fiksirovannogorazmera stiva și să adere la prima strategie. Odată ce stiva va crește atunci când amenințarea reală de depășire a stivei (de jos) poate fi îndepărtată o singură valoare. Remote astfel valoarea stack inferioară este depozitat și utilizat pentru a începe a doua etapă a algoritmului, care este similar cu ansamblul 2 este în mare parte moloz.
Într-un alt bine-cunoscut heap algoritm este considerat ca fiind o structură arborescentă cu indicii din partea de sus până jos. De colectare a gunoiului începe cu partea de sus a arborelui și merge în jos. În loc de a folosi stiva pentru a stoca indicii care necesită o prelucrare ulterioară, algoritmul utilizează indicatoarele de arbori transformându-le temporar pentru a asigura calea de întoarcere în sus copac. Acest algoritm este mai eficient în termeni de timp IS, este punctul de vedere al memoriei necesare.
Alte sisteme de purificare de memorie includ sisteme de colectare a gunoiului diferite considerând generații de colectare a gunoiului (generații), în care se realizează separarea:
• între obiecte globale care există relativ mult înainte de inițierea procesului de colectare a gunoiului, și de memorie care nu este necesară pentru a curăța;
• obiecte locale care există în mai puțin timp, și memoria pe care doriți să se întoarcă permanent la suprafața disponibilă.
Evident, un astfel de sistem reduce timpul de resturi construi și pot fi destul de eficient. În alte scheme pentru a reduce gramada de comprimare a timpului folosește două regiuni globale. Link-uri către unele prezentate în secțiunea pentru lecturi suplimentare la sfârșitul capitolului.
Indiferent de metoda de colectare a gunoiului este folosită, se poate întâmpla ca programul, pur și simplu a alerga afară de memorie disponibilă, și va fi forțat să se închidă, în cazul în care sistemul nu rezolvă această problemă, în orice alt mod. Memoria program poate fi, de asemenea, limitată din cauza de colectare a gunoiului, în cazul în care algoritmul utilizat cele mai multe ori este nevoie pentru a curăța memoria - la scurt timp după finalizarea de colectare a gunoiului, atunci când apare deja programul pregătit să continue să lucreze, o mulțime de revarsarile din nou, ceea ce necesită din nou o amintire clară. În această situație, costurile de service pentru efectuarea de colectare a gunoiului poate fi foarte importantă, și este aici, că ar fi abordare alternativă adecvată - utilizarea numărului de referință. Această metodă permite (de multe ori suficient) pentru a înlocui costurile imprevizibile de colectare a gunoiului costurile constante și previzibile.
Atunci când se utilizează numărul de referință încercarea de a șterge fiecare element de memorie heap imediat după încetarea tratamentului pentru el. Fiecare locație de memorie în heap are un număr de referință, în care numărul fix de valori, accesarea unei anumite celule. Apariția fiecărei variabile noi accesează o celulă dată, valoarea contorului crește și scade legăturile sale de dispariție. Atunci când valoarea contorului devine zero, celula poate fi returnat spațiu de memorie liber pentru distribuirea ulterioară. Această metodă este de succes, dar are unele limitări:
• Nu putea să șteargă datele pe care este asociat cu o structură de date similară cu lista circulară.
• costurile fixe asociate cu utilizarea de contoare de referință poate reduce considerabil eficiența programelor cu extrem de mici în ceea ce privește cererile de memorie.