Ce sunt pierderile de memorie și cum le puteți remedia?

Așa cum creierul este crucial pentru viața umană, memoria este la fel de importantă pentru computere. Sistemul dvs. nu poate prelua sarcini atunci când nu are suficientă memorie RAM.

Lipsa memoriei RAM și alte probleme de memorie pot apărea din cauza scurgerilor de memorie. Prin urmare, vă vom arăta cum puteți detecta scurgerile de memorie și cum le puteți remedia.

Dar înainte de asta, să înțelegem mai multe despre scurgerile de memorie și de ce ar trebui să le remediați.

Ce sunt pierderile de memorie?

Imaginați-vă o parcare chiar lângă un centru comercial, unde sunt parcate toate mașinile, indiferent dacă cumpărătorii și-au terminat sau nu cumpărăturile. În timp, nu va mai rămâne spațiu pentru parcarea vehiculelor noi, ceea ce duce la blocaje de trafic și reducând eficiența generală a mall-ului.

Sursa imagine: prateeknima.medium.com

Același lucru este și cu computerele!

Aplicațiile computerizate, similare mașinilor dintr-o parcare, pot uita să elibereze memoria folosită atunci când nu mai sunt necesare. Acest lucru încarcă memoria dvs. și nu lasă spațiu pentru ca noile sarcini să se desfășoare fără probleme, rezultând o eroare comună de memorie numită pierdere de memorie.

Un exemplu de cod pentru a prezenta scurgerea memoriei:

void memory_allocation() {
    int *ptr = (int*)malloc(sizeof(int));
}

Fragmentul de cod C de mai sus alocă o parte de memorie pentru o variabilă întreagă și atribuie locația sa de memorie indicatorului „ptr”. Dar nu există niciun cod scris pentru a dealoca memoria, ceea ce duce la pierderi de memorie.

def infinite_rec():
    return infinite_rec()

În codul Python de mai sus, nu există un caz de bază pentru a termina funcția. Deci, codul de mai sus are ca rezultat depășirea stivei și scurgeri de memorie.

Cauze comune pentru pierderile de memorie

Neglijența programatorului

Primul motiv pentru o scurgere de memorie este neglijența programatorului.

Programatorii alocă adesea date în memorie, dar uneori uită să le elibereze atunci când nu mai sunt necesare. La un moment dat, acest lucru menține întreaga memorie ocupată și nu oferă spațiu pentru sarcinile viitoare, ceea ce duce la ceea ce numim o eroare de „scurgere de memorie”.

  Cum să blocați înregistrarea cheilor de către driverele audio HP pe Elitebook-uri

Limbaje de programare

Utilizarea limbajelor de programare fără un sistem de gestionare a memoriei încorporat poate cauza pierderi de memorie.

Limbajele de programare precum Java au colectoare de gunoi încorporate pentru a se ocupa automat de gestionarea memoriei.

Dar, de exemplu, C++ nu are un colector de gunoi încorporat. Tu, programatorul, ar trebui să gestionezi manual memoria aici, ceea ce duce la scurgeri de memorie ori de câte ori uiți să curățați manual memoria.

Utilizare grea a memoriei cache

Sarcinile, datele sau aplicațiile utilizate frecvent sunt stocate în cache pentru un acces mai rapid.

Acest lucru poate duce la o eroare de scurgere a memoriei dacă articolele sunt stocate în cache, dar nu sunt șters, deși sunt învechite sau nu se mai aliniază cu tiparele dvs. de utilizare curente.

Utilizarea variabilelor globale

Variabilele globale dețin datele alocate pe toată durata de viață a aplicației. Deci, utilizarea mai multor variabile globale utilizează multă memorie pentru o perioadă mai lungă de timp și provoacă pierderi de memorie.

Structuri de date ineficiente

Dezvoltatorii își creează adesea propriile structuri de date pentru a realiza funcționalități personalizate. Cu toate acestea, erorile de scurgere de memorie apar atunci când aceste structuri de date nu pot dezaloca memoria utilizată.

Conexiuni neînchise

Neînchiderea fișierelor, bazelor de date, conexiunilor la rețea etc., după utilizare, poate duce, de asemenea, la erori de scurgere a memoriei.

Consecințele pierderilor de memorie

Performanță scăzută – Veți observa o scădere treptată a performanței aplicației sau a sistemului dvs. pe măsură ce se acumulează scurgeri de memorie. Acest lucru se datorează faptului că nu va fi nicio memorie disponibilă pentru finalizarea sarcinilor, încetinind aplicația.

Aplicații blocate – Aplicațiile rămân fără memorie pe măsură ce pierderile de memorie cresc. La un moment dat, fără memorie disponibilă, programul se blochează, ducând la pierderea datelor și la eșecul aplicației.

Vulnerabilități de securitate – Ne ștergerea corectă a datelor sensibile, cum ar fi parolele, detaliile personale sau informațiile confidențiale din memorie, după ce utilizarea acestora expune aceste date atacatorilor în timpul scurgerilor de memorie.

Epuizarea resurselor – Aplicațiile ocupă mai mult spațiu din memoria RAM atunci când rămân fără memorie din cauza scurgerilor de memorie. Acest lucru crește consumul de resurse și reduce performanța generală a sistemului.

Cum se detectează pierderile de memorie?

Inspecție manuală a codului

Examinați codul sursă pentru a găsi cazuri în care memoria este alocată, dar nu este șters după utilizare. Căutați variabile și obiecte din cod care folosesc memoria, dar nu o eliberează atunci când nu mai sunt necesare.

  Cum să vă gestionați routerul HomeKit în aplicația Apple Home

De asemenea, urmăriți sursele majore de stocare a datelor, adică asigurați-vă că structurile de date gestionează bine memoria alocată.

Analiza Codului Static

Diverse instrumente de analiză statică bine concepute analizează codul sursă al compilatorului și detectează cazurile de pierderi de memorie.

Uneori, ei urmăresc modele, reguli și erori comune din codul dvs. pentru a ghici scurgerile de memorie înainte, chiar înainte ca acestea să apară.

Instrumente de analiză dinamică

Aceste instrumente folosesc abordarea dinamică pentru a analiza codul în timpul execuției și pentru a detecta scurgerile de memorie.

Instrumentele de analiză dinamică examinează comportamentul timpului de rulare al obiectelor, funcțiilor și utilizarea memoriei acestora. Acesta este motivul pentru care aceste instrumente sunt foarte precise în detectarea scurgerilor de memorie.

Instrumente de profilare

Instrumentele de profilare vă oferă informații despre modul în care aplicația utilizează memoria.

În calitate de dezvoltator, puteți utiliza aceste informații pentru a analiza utilizarea memoriei programului și pentru a optimiza tehnicile de gestionare a memoriei pentru a preveni blocarea aplicației și problemele de degradare a memoriei.

Biblioteci de detectare a scurgerilor de memorie

Unele limbaje de programare oferă biblioteci încorporate sau terță parte pentru a detecta scurgerile de memorie în programul dvs.

De exemplu, Java are un colector de gunoi pentru a se ocupa de memorie, iar C++ oferă CrtDbg pentru gestionarea memoriei.

De asemenea, biblioteci specializate precum LeakCanary, Valgrind, YourKit etc., abordează scurgerile de memorie în diferite tipuri de aplicații.

Cum se remediază pierderea memoriei?

Identificați pierderile de memorie

Pentru a remedia pierderile de memorie, mai întâi trebuie să le identificați.

Puteți fie să faceți o inspecție manuală, fie să utilizați un instrument automat pentru a detecta dacă aplicația pierde memorie. Puteți încerca celelalte metode de detectare a scurgerilor de memorie menționate mai sus pentru a identifica scurgerile.

Identificați obiectele care cauzează scurgerea

Odată ce confirmați că aplicația pierde memorie în pasul de mai sus, ar trebui să căutați obiectele și structurile de date care provoacă scurgerea. Înțelegeți cum le este alocată memoria și unde ar trebui să elibereze memoria.

Creați cazuri de testare

Acum ai restrâns locul exact al scurgerii de memorie. Deci, creați un caz de testare pentru a vă asigura că ați identificat corect sursa scurgerii de memorie și pentru a confirma că scurgerea dispare odată ce remediați acele obiecte specifice.

Remediați codul

Adăugați codul de dealocare a memoriei pentru a elibera memoria blocată de obiectele defecte identificate. Dacă codul există deja, actualizați codul pentru a vă asigura că dealocarea corectă a memoriei utilizate.

Testează din nou

Din nou, utilizați instrumente de detectare a scurgerilor sau teste automate pentru a verifica dacă aplicația funcționează conform intenției și dacă nu există blocare a memoriei.

  Recuperați cu ușurință datele de linie

De asemenea, testați performanța și funcționalitățile aplicației dvs. pentru a vă asigura că actualizarea codului nu afectează alți factori ai aplicației.

Cele mai bune practici pentru a preveni scurgerile de memorie

Fii un programator responsabil

Ar trebui să fiți conștient de dealocarea memoriei utilizate sau eliberarea indicatorilor de memorie în timp ce scrieți codul în sine. Acest lucru va minimiza problemele de scurgere de memorie.

Vă amintiți codul de mai jos? După cum sa menționat la începutul articolului, nu există un fragment de cod de dealocare a memoriei, așa că duce la o scurgere de memorie.

void memory_allocation() {
    int *ptr = (int*)malloc(sizeof(int));
}

Iată cum tu, ca programator, poți dezaloca memoria.

delete ptr;

Utilizați limbaje de programare echipate

Limbajele de programare precum Java sau Python folosesc biblioteci de gestionare a memoriei încorporate, cum ar fi colectoarele de gunoi, pentru a gestiona automat pierderile de memorie.

Deși treceți cu vederea câteva cazuri, aceste instrumente încorporate le gestionează, prevenind potențialele scurgeri de memorie.

Prin urmare, vă recomand să utilizați astfel de limbaje de programare în care managementul memoriei este încorporat.

Referințe circulare

Evitați referințele circulare în programul dvs.

Referințele circulare urmează o buclă închisă de obiecte care se referă unele la altele. De exemplu, obiectul a se referă la b, obiectul b se referă la c și obiectul c se referă din nou la a, fără sfârșit în buclă. Deci, referințele circulare duc la o buclă infinită, provocând scurgeri de memorie.

Minimizați utilizarea variabilelor globale

Ar trebui să evitați utilizarea variabilelor globale dacă vă îngrijorează eficiența memoriei. Variabilele globale vă consumă memoria pe tot parcursul rulării aplicației, ceea ce este o practică proastă în gestionarea memoriei.

Deci, treceți la variabilele locale. Acestea sunt eficiente în memorie, deoarece eliberează memoria odată ce apelul funcției este finalizat.

Variabilele globale arată după cum urmează, dar le folosesc numai atunci când este necesar.

int x = 5 // Global variable
void func(){
    print(x)
}

Dar utilizați variabilele locale după cum urmează:

void func(){
    int x = 5 // Local variable
    print(x)
}

Limitați memoria cache

Setați o limită a memoriei pe care o poate folosi memoria cache. Uneori, toate sarcinile pe care le faceți în sistem vor fi împinse în memoria cache, iar această stocare cache acumulată duce la pierderi de memorie.

Deci, limitarea memoriei cache poate preveni scurgerile de memorie.

Testează bine

Includeți teste de scurgeri de memorie în faza dvs. de testare.

Creați teste automate și acoperiți toate cazurile marginale pentru a detecta scurgerile de memorie înainte de a lansa codul în producție.

Echipați instrumente de monitorizare

Utilizați instrumente automate de profilare pentru a vă monitoriza utilizarea memoriei. Urmărirea în mod regulat a utilizării memoriei vă ajută să identificați potențialele scurgeri și să le remediați din timp.

Visual Studio profiler, NET Memory profiler și JProfiler sunt câteva instrumente bune în acest context.

Concluzie

Gestionarea eficientă a memoriei este necesară pentru a atinge performanța maximă a aplicației, iar scurgerile de memorie nu pot fi ignorate în acest context. Pentru o gestionare eficientă a memoriei, ar trebui să gestionați scurgerile de memorie și să preveniți ca acestea să apară în viitor. Acest articol este despre cum puteți face acest lucru.

V-am arătat diferite metode pentru a detecta scurgerile de memorie, pași dovediți pentru a le remedia și practici pe care le puteți urma pentru a evita scurgerile viitoare de memorie.

Apoi, puteți explora, de asemenea, cum să remediați eroarea „memorie lipsită” în Windows în decurs de 5 minute.