Delphi's ondersteuning voor objectgeoriënteerd programmeren is rijk en krachtig. Klassen en objecten maken modulaire code-programmering mogelijk. Samen met meer modulaire en complexere componenten komen meer verfijnde en complexere bugs.
Hoewel het ontwikkelen van applicaties in Delphi (bijna) altijd leuk is, zijn er situaties waarin je het gevoel hebt dat de hele wereld tegen je is.
Wanneer u een object in Delphi moet gebruiken (maken), moet u het geheugen vrijmaken dat het heeft verbruikt (eenmaal niet meer nodig). Zeker, de try / eindelijk geheugenbewakingsblokken kunnen u helpen geheugenlekken te voorkomen; het is nog steeds aan jou om je code te beveiligen.
Een geheugenlek (of bron) treedt op wanneer het programma de mogelijkheid verliest om het geheugen vrij te maken dat het verbruikt. Herhaalde geheugenlekken zorgen ervoor dat het geheugengebruik van een proces onbeperkt groeit. Geheugenlekken zijn een serieus probleem - als u een code heeft die geheugenlekken veroorzaakt, in een applicatie die 24/7 draait, zal de applicatie al het beschikbare geheugen opeten en zal de machine uiteindelijk niet meer reageren.
De eerste stap om geheugenlekken te voorkomen, is te begrijpen hoe ze optreden. Wat volgt is een discussie over enkele veel voorkomende valkuilen en best practices voor het schrijven van niet-lekkende Delphi-code.
In de meeste (eenvoudige) Delphi-toepassingen, waarbij u de componenten (knoppen, memo's, bewerkingen, enz.) Gebruikt die u op een formulier neerzet (tijdens het ontwerpen), hoeft u zich niet al te veel zorgen te maken over geheugenbeheer. Nadat het onderdeel op een formulier is geplaatst, wordt het formulier de eigenaar en maakt het geheugen vrij dat door het onderdeel is ingenomen zodra het formulier is gesloten (vernietigd). Form, als eigenaar, is verantwoordelijk voor geheugendeallocatie van de componenten die het host. Kort gezegd: componenten op een formulier worden automatisch aangemaakt en vernietigd
In elke niet-triviale Delphi-toepassing wilt u Delphi-componenten tijdens runtime instantiëren. U zult ook enkele van uw eigen aangepaste klassen hebben. Stel dat u een klasse TDeveloper hebt die een methode DoProgram heeft. Wanneer u nu de klasse TDeveloper moet gebruiken, maakt u een instantie van de klasse door de aan te roepen creëren methode (constructor). De methode Create wijst geheugen toe voor een nieuw object en retourneert een verwijzing naar het object.
var
zarko: TDeveloper
beginnen
zarko: = TMyObject.Create;
zarko.DoProgram;
einde;
En hier is een eenvoudig geheugenlek!
Wanneer u een object maakt, moet u het geheugen verwijderen dat het heeft ingenomen. Om het geheugen vrij te maken dat een toegewezen object heeft, moet u de Vrij methode. Om helemaal zeker te zijn, moet je ook het try / eindelijk-blok gebruiken:
var
zarko: TDeveloper
beginnen
zarko: = TMyObject.Create;
proberen
zarko.DoProgram;
Tenslotte
zarko.Free;
einde;
einde;
Dit is een voorbeeld van veilige geheugentoewijzing en deallocatiecode.
Enkele waarschuwende woorden: als u een Delphi-component dynamisch wilt instantiëren en deze ergens later expliciet wilt bevrijden, geef dan altijd nul door als eigenaar. Als u dit niet doet, kan dit onnodige risico's en prestatie- en codeonderhoudsproblemen veroorzaken.
Naast het maken en vernietigen van objecten met behulp van de methoden Maken en Gratis, moet u ook heel voorzichtig zijn bij het gebruik van "externe" (bestanden, databases, enz.) Bronnen.
Stel dat u een tekstbestand moet bewerken. In een heel eenvoudig scenario, waarbij de AssignFile-methode wordt gebruikt om een bestand op een schijf aan een bestandsvariabele te koppelen wanneer u klaar bent met het bestand, moet u CloseFile aanroepen om de bestandsingang vrij te maken om te kunnen worden gebruikt. Dit is waar u geen expliciete oproep heeft voor 'Gratis'.
var
F: TextFile;
S: string;
beginnen
AssignFile (F, 'c: \ somefile.txt');
proberen
Readln (F, S);
Tenslotte
Sluitbestand (F);
einde;
einde;
Een ander voorbeeld is het laden van externe DLL's uit uw code. Wanneer u LoadLibrary gebruikt, moet u FreeLibrary aanroepen:
var
dllHandle: THandle;
beginnen
dllHandle: = Loadlibrary ('MyLibrary.DLL');
// doe iets met deze DLL
als dllHandle 0 dan FreeLibrary (dllHandle);
einde;
Hoewel met Garcia voor .NET de garbage collector (GC) de meeste geheugentaken beheert, is het mogelijk om geheugenlekken te hebben in .NET-toepassingen. Hier is een artikelbespreking GC in Delphi voor .NET.
Naast het schrijven van modulaire geheugenveilige code, kan het voorkomen van geheugenlekken worden gedaan met behulp van enkele beschikbare tools van derden. Delphi Memory Leak Fix Tools helpen u bij het vinden van Delphi-toepassingsfouten zoals geheugenbeschadiging, geheugenlekken, geheugentoewijzingsfouten, variabele initialisatiefouten, variabele definitieconflicten, aanwijzerfouten en meer.