Angenommen, eine Anwendung mit einigen Formularen und nur einem Datenmodul wird beim Start erstellt.
Im Ereignis DM1.OnCreate
wird ein TStringList
erstellt, das zur Laufzeit verwendet wird.
Wir wissen, dass beim Beenden der Anwendung alle Dinge zerstört werden und der Speicher automatisch freigegeben wird. Das Freigeben von Daten kann einige Zeit in Anspruch nehmen. Daher ist es nicht immer ratsam, sich beim Herunterfahren Gedanken über Speicherlecks zu machen. Siehe zum Beispiel diese Antwort von Barry Kelly oder diesen Beitrag von Raymond Chen.
Außerdem meldet FastMM das Speicherleck, wenn ich TStringList.Free
nicht zu DM1.OnDestroy
hinzufüge. Dies stellt sich als ein Problem bei der Suche nach anderen Speicherlecks heraus, über die ich mich wirklich Gedanken machen sollte.
Also im Grunde frage ich ob / warum / wann ich Objektinstanzen freigeben sollte, die von der Anwendung oder dem Betriebssystem freigegeben werden (Windows in diesem speziellen Fall). Gibt es einen anderen gültigen Fall, bei dem Speicherlecks nicht gesucht werden?
HINWEIS : In diesem speziellen Fall wird das Datenmodul nicht mehrmals erstellt oder neu erstellt. Es wird überhaupt kein Speicherleck mehr geben, außer dem einen. Die Datenmodul-Schrottquelle:
%Vor%Aus dem gleichen Grund befürworte ich (Untertreibung), dass ich keine Compiler-Hinweise oder Warnungen in einem Projekt hinterlasse, sauber nach dir selbst und VERLASSEN SIE KEINE MEMORY LEAK! JETZT!
Nun bedeutet das nicht unbedingt, dass Sie alles im Destructor Ihres DataModuls freilassen müssen, wenn Sie einen starken Argument dafür haben, es nicht zu tun, aber in diesem Fall müssen Sie Ihr Speicherleck registrieren damit es nicht gemeldet wird. (Und legen Sie einen sehr sichtbaren Kommentar, um zu rechtfertigen und zu erklären, warum)
Aber bedenken Sie, dass Sie dieses Projekt in einem Jahr verlassen können, dass jemand anderes es verwaltet und eine neue Geschäftsanforderung hat, mehrere DataModule zu erstellen ... Die Chancen stehen gut, wenn sie das Innere Ihres Codes nicht kennen Gut genug, sie werden darauf vertrauen, dass Ihr Code sauber ist und es wird wahrscheinlich zu Problemen kommen.
Ich würde daher dringend davon abraten, nicht zu befreien, außer in einem sehr speziellen und erwarteten und dokumentierten Fall ...
PS: Ich habe das gesehen und musste die ganze Zeit über so viele Speicher löschen, dass ich sogar einige CodeRage-Sitzungen über die Bekämpfung von Speicherlecks durchführte ...
Updayte: Hier ist der Link zum Herunterladen der dieser CodeRage-Sitzung . .
Meine Antwort kann als philosophisch betrachtet werden, aber der Hauptgrund ist, dass jede Handlung (oder Abwesenheit davon) Konsequenzen hat. Ich habe über dein Beispiel und wahrscheinlich über andere Beispiele nachgedacht und ich sehe einen guten Grund, das Objekt zu befreien. Jedes Mal, wenn ich denke, dass ich das befreiende Objekt ignorieren kann, erhöht sich die Wahrscheinlichkeit, dass dies in einer anderen, vielleicht ernsteren Situation nicht geschieht. Ein anderes Beispiel ist die Angewohnheit, "versuche endlich zu beenden", überall, wo etwas zugewiesen oder freigegeben wird. Es ist mir egal, ob ich im Ausnahmefall befreie, aber diese Gewohnheit hilft mir, undicht zu werden
Verwenden Sie RegisterExpectedMemoryLeak
für die absichtlichen Speicherlecks. Die Routine hat einige überladene Versionen, von denen eine mit einer Objektklasse ausgestattet werden kann:
oder besser, registrieren Sie den Zeiger selbst:
%Vor%In diesem Fall werden die unerwarteten Speicherlecks normal angezeigt und können nicht mit dieser speziellen String-Liste verwechselt werden.
Lassen Sie mich antworten, indem Sie eine Frage stellen.
Können Sie mit Sicherheit sagen, dass der Lebenszyklus des Datenmoduls immer an die Lebensdauer der Anwendung gebunden ist oder Sie nie zusätzliche Instanzen erstellen müssen davon?
Wenn Sie mit Ja antworten, können Sie die Standard-Speicherverwaltungspraktiken ignorieren.
Wenn Sie mit Nein antworten, sollten Sie sicherstellen, dass das Objekt nach sich selbst aufgeräumt wird.
Das wird erledigt, wenn Sie ein Objekt freigeben, möglicherweise mehr als nur die Freigabe des Speichers.
Beachtet ein Datenbankobjekt, das Transaktionen ausführt und alle gestarteten Transaktionen im Ondestroy beendet.
Wenn du nicht freirufst, wird ondestroy nicht gefeuert und du erhältst eventuell gesperrte Tabellen.
Tags und Links memory-leaks delphi free fastmm