Înțelegeți și preveni scurgerile de memorie din Delphi

DelphiSuportul pentru programarea orientată pe obiecte este bogat și puternic. Clasele și obiectele permit programarea modulară a codurilor. Alături de componente mai modulare și mai complexe vin mai sofisticate și mai complexe gandaci.

În timp ce se dezvoltă aplicații în Delphi este (aproape) mereu distractiv, există situații când simți că întreaga lume este împotriva ta.

Ori de câte ori trebuie să utilizați (să creați) un obiect în Delphi, trebuie să eliberați memoria pe care a consumat-o (o dată nu mai este nevoie). Cu siguranță, încercați / în sfârșit blocurile de protecție a memoriei vă pot ajuta să preveniți scurgerile de memorie; îți rămâne în sarcină să îți protejezi codul.

O scurgere de memorie (sau resursă) apare atunci când programul pierde capacitatea de a elibera memoria pe care o consumă. Scurgerile de memorie repetate fac ca utilizarea memoriei unui proces să crească fără limite. Scurgerile de memorie sunt o problemă gravă - dacă aveți un cod care provoacă scurgeri de memorie, într-o aplicație care rulează 24/7, aplicația va consuma toată memoria disponibilă și va face ca aparatul să nu mai răspundă.

instagram viewer

Scurgeri de memorie în Delphi

Primul pas pentru evitarea scurgerilor de memorie este de a înțelege modul în care apar. Ceea ce urmează este o discuție despre unele capcane comune și cele mai bune practici pentru scrierea codului Delphi care nu scurge.

În majoritatea aplicațiilor Delphi (simple), în care utilizați componentele (Butoane, Memos, Editări etc.), renunțați la un formular (la momentul proiectării), nu trebuie să vă preocupați prea mult de gestionarea memoriei. Odată ce componenta este plasată pe un formular, formularul devine al său proprietar și va elibera memoria preluată de componentă odată ce formularul va fi închis (distrus). Formularul, în calitate de proprietar, este responsabil pentru eliminarea memoriei componentelor găzduite. Pe scurt: componentele de pe un formular sunt create și distruse automat

Exemple de scurgeri de memorie

În orice aplicație non-banală Delphi, veți dori instantaneu componentele Delphi la timpul de rulare. Veți avea, de asemenea, unele dintre propriile clase personalizate. Să spunem că aveți un TDeveloper de clasă care are o metodă DoProgram. Acum, când trebuie să utilizați clasa TDeveloper, creați o instanță a clasei apelând la Crea metoda (constructor). Metoda Create alocă memorie pentru un obiect nou și returnează o referință la obiect.

var
zarko: dezvoltator TD
începe
zarko: = TMyObject. Crea;
Zarko. DoProgram;
Sfârșit;

Și iată o simplă scurgere de memorie!

Ori de câte ori creați un obiect, trebuie să dispuneți de memoria ocupată de acesta. Pentru a elibera memoria unui obiect alocat, trebuie să apelați la Liber metodă. Pentru a fi perfect sigur, ar trebui să utilizați și blocarea try / finalment:

var
zarko: dezvoltator TD
începe
zarko: = TMyObject. Crea;
încerca
Zarko. DoProgram;
in cele din urma
Zarko. Liber;
Sfârșit;
Sfârșit;

Acesta este un exemplu de alocare sigură a memoriei și a codului de alocare.

Câteva cuvinte de avertizare: Dacă doriți să instaționați dinamic o componentă Delphi și să o eliberați explicit cândva mai târziu, treceți întotdeauna nul ca proprietar. Nerespectarea acestui lucru poate introduce riscuri inutile, precum și probleme de performanță și de întreținere a codului.

Pe lângă crearea și distrugerea obiectelor folosind metodele Create and Free, trebuie să fiți foarte atenți și atunci când utilizați resurse „externe” (fișiere, baze de date etc.).
Să zicem că trebuie să acționați cu un fișier text. Într-un scenariu foarte simplu, unde metoda AssignFile este utilizată pentru a asocia un fișier pe un disc cu un fișier variabilă când ați terminat cu fișierul, trebuie să apelați CloseFile pentru a elibera mânerul fișierului pentru a începe folosit. Aici nu aveți un apel explicit la „Free”.

var
F: TextFile;
S: șir;
începe
AssignFile (F, 'c: \ somefile.txt');
încerca
Readln (F, S);
in cele din urma
CloseFile (F);
Sfârșit;
Sfârșit;

Un alt exemplu include încărcarea DLL-urilor externe din codul dvs. Ori de câte ori utilizați LoadLibrary, trebuie să apelați FreeLibrary:

var
dllHandle: Thandle;
începe
dllHandle: = Loadlibrary ('MyLibrary. DLL ');
// fă ceva cu acest DLL
dacă dllHandle <> 0 atunci FreeLibrary (dllHandle);
Sfârșit;

Scurgeri de memorie în .NET?

Deși cu Delphi for .NET, colectorul de gunoi (GC) gestionează majoritatea sarcinilor de memorie, este posibil să existe scurgeri de memorie în aplicațiile .NET. Iată o discuție despre articol GC în Delphi pentru .NET.

Cum să lupte împotriva scurgerilor de memorie

Pe lângă scrierea codului modular de siguranță pentru memorie, prevenirea scurgerilor de memorie se poate face folosind unele dintre instrumentele terților disponibile. Delphi Instrumente de remediere a scurgerilor de memorie te ajută să prinzi aplicația Delphi erori cum ar fi corupția memoriei, scurgeri de memorie, erori de alocare a memoriei, erori de inițializare variabilă, conflicte de definiție a variabilelor, erori de indiciu și multe altele.