![]() |
|
URL dieses Artikels:
Delphi 8 und der Garbage Collector
Frage: Ist es möglich dass der Garbage Collector von .NET nicht richtig funktioniert? Wenn ich Formulare auf und zu mache, benötigt das Programm immer mehr Speicher, der erst beim Beenden meiner mit Delphi 8 kompilierten VCL.NET-Anwendung freigegeben wird. In dem geöffneten Formular werden Grafiken geladen und angezeigt, wobei ich das Formular am Ende über FormOjbect:=nil freigebe.
Antwort: Der Garbage Collector (GC) arbeitet im Alltag stabil und zuverlässig. Allerdings kümmert sich der GC nur um den managed Code, alle direkten Allozierungen von nativen Win32-Handles etc. müssen wie gehabt in eigener Regie freigegeben werden. Dieses Hintergründe treten bei einer VCL.NET-Anwendung deutlicher hervor als bei einer FCL-Anwendung, da die VCL.NET intern sehr häufig über P/Invoke direkt das Win32-API bemüht. Wenn der GC mit Hintergrund-Modus (siehe .NET Framework Configuration | Eigenschaftn von My Computer | Garbage collection mode "Für Benutzeranwendungen im Hintergrund ausführen") ausgeführt wird, läuft er unter Last in der Regel erst dann an, wenn eine neue Speicheranforderung nicht genug freien Speicherplatz vorfindet. Dann allerdings rattert die Festplatte erst einmal längere Zeit. Wenn man dieses Verhalten nicht möchte, muss man entweder den GC im Vordergrund betreiben oder freiwillig die nicht mehr benötigten (größeren) Objekte mit Dispose (FCL) beziehungsweise Release oder Free (VCL.NET) freigeben. Der folgende Test demonstriert das Verhalten. Bei 1. Test mit einem leeren VCL.NET-Formular, auf dem nur eine TTimer-Komponente liegt, ist kein Hochlaufen des Working Set des Prozesses zu beobachten (nach 100 Aufrufen ist das Working Set des Prozesses nur um 4 kByte größer geworden). Auch beim 2. Test mit dem Grafik-Formular pendelt das Working Set zwischen 2 stabilen Grenzen. Allerdings lege ich aber freiwillig durch den Relaese-Aufruf den Zeitpunkt des Freigebens der erzeugten Formular-Instanz selbst fest, so dass der Speicherverbrauch des Prozesses meiner Testanwendung erst gar nicht hochläuft. Wird der Aufruf von Form3.Release jedoch durch Form3 := nil ersetzt, ballert man sich das Working Set des Prozesses bei 100 Aufrufen des Grafik-Formulars um 70 MByte zu. Es ist somit auch unter .NET in jedem Fall sinnvoll, derart große Objekte freiwillig explizit (und somit zu einem definierten Zeitpunkt) freizugeben, wenn man derartige Zuwächse nicht möchte. a) Hauptformular unit FormMain;b) aufgerufenes leeres Formular unit FormEmpty;c) aufgerufenes Grafik-Formular lädt eine 385 kByte-Bitmap unit FormGrafik; |
|
© 2002 Software & Support Verlag GmbH. Vervielfältigung
nur mit Genehmigung des Verlags. Alle Markennamen sind in der Regel
eingetragene Warenzeichen der entsprechenden Unternehmen oder Organisationen.
Fragen? ... zum Angebot des Software & Support Verlags: info@entwickler.com ... zu dieser Website: webmaster@entwickler.com |