Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Memory Leak durch Thread? (https://www.delphipraxis.net/142330-memory-leak-durch-thread.html)

iphi 26. Okt 2009 12:08


Memory Leak durch Thread?
 
Hallo,

ich glaube, ich habe ein Memoryleak programmiert und ich weiß nicht warum.

Ich habe ein Threadobjekt, welches vom Haupt-VCL Programm erzeugt und gestartet, beendet und wieder vernichtet wird.

Nach Vernichtung des Threadobjekts zeigt der Taskmanager für mein Programm mehr Speicherverbrauch an als vor der Erzeugung.

Hier der prinzipielle Ablauf:

Delphi-Quellcode:
Capture := TCapture.Create(false);
...warte auf ein Ereignis, dann
Capture.Terminate;
setze alle dynamischen Objekte in Capture auf Länge 0.
Capture.Destroy;
Das Ganze lässt sich auch wiederholen. Nach jedem Threadlauf wächst der Speicherbedarf weiter an.

Hat jemand nen Tipp für mich?

Gruß, Thomas

sirius 26. Okt 2009 12:22

Re: Memory leak?
 
1. Man ruft Free anstatt Destroy auf. Dürfte aber nicht viel ändern.
2. Der Taskmanager ist erstens ungenau und zweitens weis der eh nicht, was gerade dein Speichermanager macht. Dein Speichermanager reserviert mal schnell einen 4kB Block auch wenn du nur ein Byte brauchst und gibt den Block erst am Ende des Programms wieder frei (er ist besser organisiert, als es jetzt klingt).
3. Versuche deswegen mal bei deinem Speichermanager nachzufragen (getHeapStatus) oder nutze FastMM der deinen Speicher überwacht. Wenn du dann immer noch Speicherlöcher findest, dann erst tiefer ins Programm schauen.

Luckie 26. Okt 2009 12:25

Aussagekräftiger Titel
 
Bitte gib deinem Beitrag einen aussagekräftigen Titel. Der jetzige Titel lässt nicht erkennen, um was für ein Problem oder Frage es sich handelt. Um den Titel zu ändern, editiere einfach deinen ersten Beitrag. Damit erleichterst du das Auffinden deines Beitrages mit der Suche und ersparst anderen Mitglieder ein unnötiges Öffnen deines Beitrages.

himitsu 26. Okt 2009 12:28

Re: Memory leak?
 
Delphi-Quellcode:
setze alle dynamischen Objekte in Capture auf Länge 0.
das kann alles mögliche bedeuten
und meine :glaskugel: sagt: so hab ich keinen Tipp

das mit dem Destroy steht sogar in der OH drinnen
meine OH sagt (TObject.Destroy)
Rufen Sie Destroy nicht direkt auf. Verwenden Sie stattdessen Free. Die Methode Free überprüft, ob die Objekt-Referenz nicht bereits nil ist und ruft Destroy nur bei Bedarf auf.

iphi 26. Okt 2009 18:29

Re: Memory Leak durch Thread?
 
Zitat:

setze alle dynamischen Objekte in Capture auf Länge 0.

das kann alles mögliche bedeuten
Ich benutze im Thread ein paar dynamische Felder, die ich zum Schluss mit setlength(...,0) wieder auf Länge Null schrumpfe.

Ich habe definitiv ein Speicherleck. Jeder Threaddurchlauf erhöht das Prozessmemory um 8k, mit GetProcessMemoryInfo im Programm verifiziert.

Hat jemand nen Tipp, wie man den Übeltäter strategisch einkreisen könnte?

mkinzler 26. Okt 2009 18:31

Re: Memory Leak durch Thread?
 
Was legst du in den dynamischen Strukturen ab?

iphi 26. Okt 2009 18:35

Re: Memory Leak durch Thread?
 
Zitat:

Was legst du in den dynamischen Strukturen ab?
Datenblöcke vom Audiodatenstrom.

mkinzler 26. Okt 2009 18:37

Re: Memory Leak durch Thread?
 
Das SetLength() löscht zwar das dynamische Array aber nicht die TCapture(?) Strukturen, die darin verwaltet werden.

iphi 26. Okt 2009 18:42

Re: Memory Leak durch Thread?
 
Meine dynamischen Felder enthalten nur Chars, keine Strukturen.

Die TCapture-Thread-Struktur sollte doch eigentlich mit Capture.Free gelöscht werden.???

Klaus01 26. Okt 2009 19:42

Re: Memory Leak durch Thread?
 
Guten Abend,

hast Du schon FastMM4 eingebunden um zu sehen
ob Du wirklich ein Leck hast.

Grüße
Klaus

iphi 26. Okt 2009 19:56

Re: Memory Leak durch Thread?
 
Nein, hab ich nicht. Bekomme ich mit GetProcessMemoryInfo nicht dieselbe Aussage?

Ich habe sicher ein Leck. Ich habe einen zweiten Testthread ins Programm eingebaut und der macht mir keine dauerhafte Vergrößerung des Prozessspeichers.

Medium 26. Okt 2009 19:58

Re: Memory Leak durch Thread?
 
FastMM ist z.B. so ein Profiler, die ich in deinem anderen Thread-Thread (:)) erwähnt hatte. Und nein, er macht NICHT das selbe. Probier's einfach mal.

Edit: Und wenn alles nix hilft (probier FastMM aber wirklich vorher), zeig uns doch mal den gesamten Code deiner Thread-Klasse.

iphi 26. Okt 2009 20:23

Re: Memory Leak durch Thread?
 
FastMM ist offenbar ein mächtiges Tool, wenn man es zu nutzen weiß.

Ich habs mal ganz naiv eingebunden und festgestellt, dass nicht nur meine Threadobjekte lecken:

Zitat:

This application has leaked memory. The small block leaks are (excluding expected leaks registered by pointer):

13 - 20 bytes: TObjectList x 3
21 - 36 bytes: TWinHelpViewer x 1
37 - 52 bytes: THelpManager x 1
Was lerne ich jetzt daraus? Wie kann ich vorgehen um die Lecks zu stopfen?
Übrigens: Ich benutze garkeine Objekte vom Typ TWinHelpViewer bzw. THelpManager in meiner App.

???

iphi 26. Okt 2009 20:36

Re: Memory Leak durch Thread?
 
P.S.

Die obigen FastMM4 Fehlermeldungen bekomme ich nur, wenn ich meinen Code in der Delphi6PE IDE laufen lasse. Jedes Dummyprojekt erzeugt in der Delphi6PE IDE dieselben Fehler. In der Delphi7PE IDE werden keine solchen Fehler ausgegeben. ????

himitsu 26. Okt 2009 21:04

Re: Memory Leak durch Thread?
 
Für solche aufeinanderfolgende Posts gibt es einen Editbutton, um nicht zu Pushen.
http://www.delphipraxis.net/dpX_faq_...?faq=Q_27#Q_27

Dann sind einige Speicherlecks "Absicht" und Andere ... wie hast du FastMM eingebunden?
Die Unit muß als Allererste in der DPR eingetragen sein.

iphi 26. Okt 2009 21:55

Re: Memory Leak durch Thread?
 
Ok, werde künftig editieren.
Zitat:

Die Unit muß als Allererste in der DPR eingetragen sein.
Hab ich genau so gemacht. Stand auch so in der Readme. Habe ein LogFile erzeugen lassen.

Die Delphi6 Personal und Delphi7 Personal IDE verhalten sich definitiv unterschiedlich.

P.S.
Jetzt wirds noch besser: in D7 ist auch das Thread-Leck verschwunden. FastMM scheint aber zu funktionieren. Wenn ich das Programm beende, ohne das Thread-Object zu free-en, dann wird ein Speicherleck angezeigt, was ja auch Sinn macht.

Trotzdem zeigt der Prozessspeicher mit jedem neuen Free-Create-Zyklus einen Prozessspeicherzuwachs. Muss mich das nun beunruhigen? Ich beabsichtige den Thread viele tausende Male neu zu starten.

sirius 27. Okt 2009 07:16

Re: Memory Leak durch Thread?
 
Wenn du die Anzeige im Taskmanager meinst, braucht dich das nicht zu beunruhigen. Der Speichermanager (hier FastMM) weis es besser ;)

Du brauchst übrigens deine dynamischen Variablen (Strings, Arrays) nicht auf Länge 0 setzen, dass passiert automatisch.

iphi 27. Okt 2009 10:29

Re: Memory Leak durch Thread?
 
Zitat:

Der Speichermanager (hier FastMM) weis es besser
Das ist offenbar wirklich richtig und ziemlich erstaunlich.

Ich habe mal meinen Thread 2 Stunden lang alle Sekunde gestartet, wieder beendet und ge-"free"d und den Prozessspeicher dabei beobachtet. Der wuchs dabei eine Zeit lang in 12k Schritten um insgesamt ca. 700k. Danach stabilisierte der sich aber und wuchs nicht weiter. Man fragt sich dabei warum.

FastMM hat beim Beenden des Programms kein Memoryleck gefunden. Mein Code ist also offenbar ok :-)

Noch eine Frage:
Ist es sinnvoll FastMM dauerhaft eingebunden zu lassen oder sollte man das am Ende der Programmentwicklung wieder rausschmeissen?

Zitat:

Du brauchst übrigens deine dynamischen Variablen (Strings, Arrays) nicht auf Länge 0 setzen, dass passiert automatisch.
Das stimmt auch. FastMM meldet kein Problem, wenn man die Felder nicht wieder auf Länge Null zurücksetzt. Der Prozessspeicher sieht das wiederum anders (Fragmentierungsproblem?)

himitsu 27. Okt 2009 11:01

Re: Memory Leak durch Thread?
 
FastMM versucht etwas zu optimieren,
dabei sucht er z.B. nicht ständig seinen ganzen Speicher nach 'nem freien Platz passender Größe ab, wenn irgendetwas Speicher haben will, sondern er sucht nur ab einer bestimmten Position (ab da wo zuletzt freier Speicher gefunden wurde).
Wenn jetzt etwas freigegeben wird, dann entsteht vor dem gemerkten Positionszeiger eine Lücke, welche zwar in FastMM frei, aber dennoch bei Windows registirert ist.
Nun wird aber erstmal danach gesucht, so daß einige Lücken entstehen, welche Dank der "Optimierung" eine Weile bestehen bleiben, bis irgendwann der Positionszeiger hier wieder vorbeikommt.

> das ist jetzt alles nur "vereinfacht" ausgedrückt.

Also die Suche ist so zwar schneller, aber er braucht etwas mehr Speicher, welchen du hier entdeckt hast.

iphi 27. Okt 2009 11:11

Re: Memory Leak durch Thread?
 
Zitat:

Noch eine Frage:
Ist es sinnvoll FastMM dauerhaft eingebunden zu lassen oder sollte man das am Ende der Programmentwicklung wieder rausschmeissen?
???

sirius 27. Okt 2009 11:37

Re: Memory Leak durch Thread?
 
Du brauchst sowieso irgendeinen Speichermanager. Delphi hat einen dabei. Und ich glaube ab einer bestimmten Version >7 ist es sogar FastMM.

Du kannst ihn also getrost drinnen lassen, solltest nur diverse Debuggin-Funktionen wie Meldungsfenster und Log-Funktionen ausschalten

Edit: Du kannst auch einen eigenen programmieren (setMemorymanager).

himitsu 27. Okt 2009 11:43

Re: Memory Leak durch Thread?
 
Laß ihn bei dir drinnen, der ist Schneller als der alte DelphiMM.

Ansonsten ist eine etwas ältere und leicht abgespreckte/angepaßte Version des Fast MM seit D2006 oder D2007 schon im Delphi eingebaut.

Die haben mitbekommen, daß ihrer doch nicht soooo Optimal ist und haben ihn daher ausgetauscht.
Der DelphiMM hatte sich aber auch seit vielen Jahren nicht weiterentwickelt. :nerd:


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:43 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz