O scurgere de memorie este un proces de reducere necontrolată a cantității de memorie RAM liberă sau a memoriei virtuale a unui computer asociat cu erori în rularea programelor care nu eliberează la timp memoria de date inutile sau cu erori în serviciile de control al memoriei sistemului.
Luați în considerare următorul fragment de cod C++ :
char * pointer = NULL ; pentru ( int i = 0 ; i < 10 ; i ++ ) { pointer = new char [ 100 ]; } șterge [] pointer ;Acest exemplu creează un obiect în heap pe a treia linie. Codul de pe a 3-a linie este executat de 10 ori, iar de fiecare dată adresa noului obiect suprascrie valoarea stocată în pointer. Pe a 5-a linie, obiectul creat la ultima iterație a buclei este șters. Totuși, primele 9 obiecte rămân în memoria dinamică și, în același timp, nu mai există variabile în program care să stocheze adresele acestor obiecte. Adică în a 5-a linie este imposibil să accesezi sau să ștergi primele 9 obiecte.
Memoria dinamică este o resursă limitată. Memoria dinamică a unui program este de obicei gestionată de o bibliotecă de limbaj de programare care rulează ea însăși peste memoria dinamică furnizată de sistemul de operare.
Scurgerile de memorie duc la faptul că consumul de memorie al programului crește necontrolat, ca urmare, mai devreme sau mai târziu, restricțiile arhitecturale ale mediului de execuție ( sistem de operare , mașină virtuală , computer ) intră în vigoare și apoi o nouă alocare de memoria devine imposibilă. În această situație, un program care solicită memorie se blochează de obicei . Acest lucru se poate întâmpla, prin coincidență, cu un program complet diferit după ce programul, supus unor scurgeri, epuizează toată memoria computerului.
Există diferite modalități de a preveni scurgerile de memorie.
De exemplu, FORTRAN-77 abandonează complet utilizarea mecanismelor de alocare dinamică a memoriei, care elimină astfel de erori, dar limitează semnificativ funcționalitatea programelor.
Deținerea de pointeri vă permite să conveniți cumva asupra duratei de viață a pointerului și asupra duratei de viață a obiectului la care se referă. Cu toate acestea, folosirea deținerii de pointeri nu ajută în cazul referințelor circulare între obiecte. (pentru detalii, consultați modelul „ Achiziția de resurse este inițializare ”)
Unele limbaje de programare (de exemplu, limbaje de platformă Oberon , Java , .NET ) oferă instrumente pentru eliberarea automată a memoriei nefolosite („ garbage collector ”, în engleză garbage collector ). Colectatorii de gunoi rezolvă și problema referințelor circulare, dar colectarea gunoiului este o operațiune care necesită mult resurse. Costul utilizării unor astfel de instrumente este viteza sistemului și, cel mai important, colectarea gunoiului introduce pauze neașteptate în program, ceea ce este inacceptabil în sistemele în timp real .
Colectarea gunoiului a fost inventată de John McCarthy în jurul anului 1959 , în timp ce dezvolta limbajul de programare Lisp , a cărui structură face gestionarea manuală a memoriei extrem de dificilă.
În cazurile în care nu este posibilă eliminarea scurgerilor de memorie, de exemplu, când se utilizează codul furnizat ca plug-in-uri și realizat de dezvoltatori terți, se folosește o modalitate particulară de a ignora scurgerile. Codul scurs este plasat într-un program separat, iar acest program este repornit la frecvența necesară. Pornirile și repornirile programului sunt efectuate de un program extern, care furnizează și datele inițiale și preia rezultatele. Deoarece atunci când un program se termină, toată memoria pe care o pretinde de la sistemul de operare este returnată sistemului de operare, această metodă împiedică scurgerile să devină catastrofale.
Există, de asemenea, o eroare numită Handle Leak : mânerele capturate nu sunt returnate sistemului de operare.
Pentru a combate consecințele unor astfel de erori, dezvoltatorii de sisteme de operare introduc în ele funcționalități care le permit să limiteze cantitatea de memorie, numărul de mânere și cantitatea de timp de procesor disponibilă unui utilizator sau unui anumit proces.
Pentru limbajele de programare profesionale, există programe speciale de profiler care vă permit să detectați, printre altele, scurgerile de memorie.
Pentru unele limbaje de programare, există analizoare de cod statice care identifică elementele programului care pot duce la erori logice, inclusiv scurgeri de memorie. O versiune primitivă a unui astfel de analizor este implementată de aproape orice compilator al unui limbaj de nivel înalt, sub forma emiterii de așa-numite avertismente (avertismente) - mesaje despre prezența în program a constructelor care nu încalcă formal sintaxa de limbajul, dar sunt potențial eronate.
Există biblioteci pentru depanarea utilizării memoriei care vă ajută să monitorizați alocarea și dealocarea memoriei în timp ce programul rulează.