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 in einer TStringList (https://www.delphipraxis.net/138398-memory-leak-einer-tstringlist.html)

Chemiker 9. Aug 2009 22:21


Memory Leak in einer TStringList
 
Hallo,

ich habe in meinem Programm in einer TStringList ein Memory Leak.

Wie kann man eingrenzen in welcher Unit das Leak auftritt? Eine grobe Eingrenzung wo ich Suchen muss würde schon Helfen.

Bis bald Chemiker

wfoertsch 10. Aug 2009 06:45

Re: Memory Leak in einer TStringList
 
Zitat:

Zitat von Chemiker
Hallo,

ich habe in meinem Programm in einer TStringList ein Memory Leak.

Wie kann man eingrenzen in welcher Unit das Leak auftritt? Eine grobe Eingrenzung wo ich Suchen muss würde schon Helfen.

Bis bald Chemiker


Hallo,

sehr gut kannst deine Leaks mit Eurekalog finden ... einfach catch memory leaks einschalten ^^

wolle

alzaimar 10. Aug 2009 07:01

Re: Memory Leak in einer TStringList
 
FastMM4 sollte zu den gleichen Ergebnissen kommen. Der Link führt dich zu einer Seite, von der Du sowohl FastMM4 als auch eine GUI downloaden kannst.

himitsu 10. Aug 2009 07:11

Re: Memory Leak in einer TStringList
 
hier kannst du natürlich auch selber mal etwas nachschauen ... ein Leck is so'ner TStringList entsteht ja meißt nicht von alleine, also wenn du den .Objects irgendwo etwas zuweißt, dann schauen, ob dieses beim Freigeben der Liste, bzw. beim Löschen von Einträgen auch mit entfernt/freigegeben wird.

Chemiker 10. Aug 2009 18:16

Re: Memory Leak in einer TStringList
 
Hallo,

Danke für die Antworten.

@wfoertsch: Ich benutze FastMM4 schon.

@alzaimar: FastMM4 zeigt mit ja das Memory Leak an, dass Problem ist nur, er sagt es kommt in einer TStringList vor, allerdings nicht in welcher Unit. Habe mir auch die
MMProject_MemoryManager_EventLog.txt ausgeben lassen, aber dort steht kein Hinweis, oder ich bin nicht in der Lage das richtig zu lesen.

@himutsu: Das ist schon klar, allerdings bei einem umfangreichen Programm ist das leider nicht mehr so einfach.

Bis bald Chemiker

BAMatze 10. Aug 2009 18:26

Re: Memory Leak in einer TStringList
 
Hallo @Chemiker,

gleiches Problem hatte ich in meinem Projekt letztens. Es blieb mir aber nichts weiter übrig, als jede Unit/ Komponente an sich zu testen (in einem neuen Projekt, wo nur die jeweilige Komponente/ Unit drin liegt). Bei mir, war es bei TStringlist zu 80% ein vergessen des override beim Destroyer, wodurch ich zwar das Free in den Destroyer geschrieben hatte, aber ebend nicht ausgeführt wurde.

MfG
BAMatze

hoika 10. Aug 2009 18:28

Re: Memory Leak in einer TStringList
 
Hallo,

also ich benutze MemCheck,
der zeigt mir sowohl die Komponente also auch die Stelle,
wo genau der Speicher angefordert wurd.

Schau doch mal in der FastMM-Inc nach,
ob du einen Parameter nicht gesetzt hast.


Heiko

Chemiker 10. Aug 2009 19:07

Re: Memory Leak in einer TStringList
 
Hallo,

ich habe mal ein kleines Demo-Programm geschrieben und eine TStringlist nicht freigegeben.

Das ist die Log-File dazu:


Code:
--------------------------------2009/8/10 19:58:31--------------------------------
Ein Speicherblock hat Speicher verloren. Die Größe ist: 68

Aufrufstack, von wem der Block momentan belegt wird (Rücksprungadressen):
402E8A [system.pas][System][@GetMem][2648]
403A3F [system.pas][System][TObject.NewInstance][8824]
403DAE [system.pas][System][@ClassCreate][9489]
403A74 [system.pas][System][TObject.Create][8839]
41218B [sysutils.pas][SysUtils][TThreadLocalCounter.Open][16571]
41211E [sysutils.pas][SysUtils][TThreadLocalCounter.HashIndex][16552]
465A03 [uHPLDemoFastMM.pas][uHPLDemoFastMM][TForm2.FormCreate][44]
4592B3 [Forms.pas][Forms][TCustomForm.DoCreate][2756]
458EFB [Forms.pas][Forms][TCustomForm.AfterConstruction][2680]
403E1C [system.pas][System][@AfterConstruction][9537]

Der Block wird momentan für eine Objektklasse benutzt TStringList

The allocation number is: 346

Aktueller Speicherauszug von 256 Bytes, beginnend ab Zeigeradresse 7FF7C5A0:
68 74 41 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 DD 5B 73 7D 0C 01 47 00
0C 01 47 00 0C 01 47 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
62 01 00 00 8A 2E 40 00 3F 3A 40 00 AE 3D 40 00 74 3A 40 00 EC 59 46 00 90 2B 44 00 42 EF 42 00
AB F0 42 00 D0 25 44 00 AD 31 7A 75 A6 2E 40 00 5D 3A 40 00 F9 3D 40 00 FD B5 41 00 A3 3A 40 00
F1 59 46 00 90 2B 44 00 42 EF 42 00 AB F0 42 00 D0 25 44 00 38 00 00 00 68 74 41 00 9D FC 9F FA
0C FE 46 00 0C 01 47 00 0C 01 47 00 0C 01 47 00 0C 01 47 00 0C 01 47 00 0C 01 47 00 0C 01 47 00
0C 01 47 00 0C 01 47 00 0C 01 47 00 0C 01 47 00 0C 01 47 00 0C 01 47 00 62 03 60 05 0C 01 47 00
h t A . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . Ý  [  s }  . . G .
. . G . . . G . . . . . . . . . . . . . . . . . . . . . . . . .
b . . . Š  . @  . ?  : @  . ®  = @  . t : @  . ì  Y F .   +  D . B ï  B .
«  ð  B . Р %  D . *  1  z u ¦  . @  . ] : @  . ù  = @  . ý  µ  A . £  : @  .
ñ  Y F .   +  D . B ï  B . «  ð  B . Р %  D . 8  . . . h t A .   ü  Ÿ  ú
. þ  F . . . G . . . G . . . G . . . G . . . G . . . G . . . G .
. . G . . . G . . . G . . . G . . . G . . . G . b . `  . . . G .

--------------------------------2009/8/10 19:58:31--------------------------------
Diese Anwendung hat Speicher verloren. Die Größen von kleinen Speicherblöcken, die verlorengegangen sind, betragen (ausgenommen erwartete Speicherlecks, die durch Zeiger registriert wurden):

53 - 68 Bytes: TStringList x 1
Man kann nicht erkennen in welcher Unit das Leak auftritt.

Noch irgendwer eine Idee?

Bis bald Chemiker

himitsu 10. Aug 2009 19:13

Re: Memory Leak in einer TStringList
 
Delphi-Quellcode:
53 - 68 Bytes: TStringList x 1
klingt das nicht danach, als wenn du eine ganze (leere) StringList irgendwo vergessen hast freizugeben? :gruebel:
du hat nicht zufällig eine StringList in TForm2.FormCreate erstellt und in .OnDestroy nicht wieder freigegeben?

Chemiker 10. Aug 2009 19:24

Re: Memory Leak in einer TStringList
 
Hallo,

himitsu, genau. Jetzt musst Du mir nur noch verraten, wie man das in dem Log-File erkennt.

Bis bald Chemiker

himitsu 10. Aug 2009 19:32

Re: Memory Leak in einer TStringList
 
Code:
--------------------------------2009/8/10 19:58:31--------------------------------
Ein Speicherblock hat Speicher verloren. Die Größe ist: 68
                            [color=#ff0000]Größe des gefundenen Blocks ^^[/color]

Aufrufstack, von wem der Block momentan belegt wird (Rücksprungadressen):
402E8A [system.pas][System][@GetMem][2648]
403A3F [system.pas][System][TObject.NewInstance][8824]
403DAE [system.pas][System][@ClassCreate][9489]
403A74 [system.pas][System][TObject.Create][8839]
41218B [sysutils.pas][SysUtils][TThreadLocalCounter.Open][16571]
41211E [sysutils.pas][SysUtils][TThreadLocalCounter.HashIndex][16552]
465A03 [uHPLDemoFastMM.pas][uHPLDemoFastMM][TForm2.FormCreate][44]
[color=#ff0000]^^ innerhalb der Aufrufe war das hier wichtig[/color]
4592B3 [Forms.pas][Forms][TCustomForm.DoCreate][2756]
458EFB [Forms.pas][Forms][TCustomForm.AfterConstruction][2680]
[color=#ff0000]^^ dieser rief jenen auf uswusf. (Lese-/Aufrufrichtung nach oben gehend)[/color]
403E1C [system.pas][System][@AfterConstruction][9537]
[color=#ff0000]^^ das wer der erste "Auslöser" der Speicherreservierung[/color]

Der Block wird momentan für eine Objektklasse benutzt TStringList
[color=#ff0000]^^ hier steht nochmals der Typ dessen, was in dem Speicher vermutlich drin ist[/color]

The allocation number is: 346

Aktueller Speicherauszug von 256 Bytes, beginnend ab Zeigeradresse 7FF7C5A0:
68 74 41 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 DD 5B 73 7D 0C 01 47 00
0C 01 47 00 0C 01 47 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
62 01 00 00 8A 2E 40 00 3F 3A 40 00 AE 3D 40 00 74 3A 40 00 EC 59 46 00 90 2B 44 00 42 EF 42 00
AB F0 42 00 D0 25 44 00 AD 31 7A 75 A6 2E 40 00 5D 3A 40 00 F9 3D 40 00 FD B5 41 00 A3 3A 40 00
F1 59 46 00 90 2B 44 00 42 EF 42 00 AB F0 42 00 D0 25 44 00 38 00 00 00 68 74 41 00 9D FC 9F FA
0C FE 46 00 0C 01 47 00 0C 01 47 00 0C 01 47 00 0C 01 47 00 0C 01 47 00 0C 01 47 00 0C 01 47 00
0C 01 47 00 0C 01 47 00 0C 01 47 00 0C 01 47 00 0C 01 47 00 0C 01 47 00 62 03 60 05 0C 01 47 00
h t A . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . Ý  [  s }  . . G .
. . G . . . G . . . . . . . . . . . . . . . . . . . . . . . . .
b . . . Š  . @  . ?  : @  . ®  = @  . t : @  . ì  Y F .   +  D . B ï  B .
«  ð  B . Р %  D . *  1  z u ¦  . @  . ] : @  . ù  = @  . ý  µ  A . £  : @  .
ñ  Y F .   +  D . B ï  B . «  ð  B . Р %  D . 8  . . . h t A .   ü  Ÿ  ú
. þ  F . . . G . . . G . . . G . . . G . . . G . . . G . . . G .
. . G . . . G . . . G . . . G . . . G . . . G . b . `  . . . G .

--------------------------------2009/8/10 19:58:31--------------------------------
Diese Anwendung hat Speicher verloren. Die Größen von kleinen Speicherblöcken, die verlorengegangen sind, betragen (ausgenommen erwartete Speicherlecks, die durch Zeiger registriert wurden):

53 - 68 Bytes: TStringList x 1
[color=#ff0000]^^ und in de kurzen Ansich sieht man auch schon etwas, also daß z.B. anscheinend eine (x 1) TStringList noch nicht freigegeben wurde[/color]

Satty67 10. Aug 2009 19:48

Re: Memory Leak in einer TStringList
 
Sehr schön erklärt, da kann ich auch gleich was lernen ;)

Wichtig finde ich, das FastMM4 (o.ä.) von Anfang an mit dabei ist. Das hat mir bisher Suchen erspart, weil man einen Freigabe-Fehler gleich mitbekommt und dann nur im zuletzt bearbeiteten Code suchen muss (meistens...)

Chemiker 10. Aug 2009 19:51

Re: Memory Leak in einer TStringList
 
Hallo himitsu,

Code:
465A03 [uHPLDemoFastMM.pas][uHPLDemoFastMM][TForm2.FormCreate][44]
danke für den Hinweis, es ist eigentlich ganz einfach die [44], gibt die Zeilenzahl an wo die nicht freigegebene TStringlist steht.

Wenn man eine lokale TStringlist nicht freigibt steht da die Procedure in der sie Deklariert worden ist.

Bis bald Chemiker

Chemiker 10. Aug 2009 19:56

Re: Memory Leak in einer TStringList
 
Hallo Sattey67,

keine schlechte Idee, aber das Projekt ist aus mehren Modulen zusammengesetzt und ich vermute das ich beim Zusammensetzen irgend einen Fehler gemacht habe.

Bis bald Chemiker

himitsu 10. Aug 2009 20:30

Re: Memory Leak in einer TStringList
 
Zitat:

Zitat von Chemiker
Wenn man eine lokale TStringlist nicht freigibt steht da die Procedure in der sie Deklariert worden ist.

aber nur wenn man es mitloggen läßt, ansonsten steht nur die etwaige Größe und der vermutluche Inhalt da (z.B. in der kleinen MessageBox bei Programmende, wenn man sich die Belegung ausgeben läßt)

Chemiker 10. Aug 2009 20:31

Re: Memory Leak in einer TStringList
 
Hallo,


Code:
--------------------------------2009/8/10 21:26:11--------------------------------
Ein Speicherblock hat Speicher verloren. Die Größe ist: 68

Aufrufstack, von wem der Block momentan belegt wird (Rücksprungadressen):
40301A [system.pas][System][@GetMem][2648]
404693 [system.pas][System][TObject.NewInstance][8824]
404A5A [system.pas][System][@ClassCreate][9489]
4046C8 [system.pas][System][TObject.Create][8839]
4056A0 [system.pas][System][@LStrAsg][12354]
4DDC4F [IB_Services.pas][IB_Services][TpFIBCustomService.Create][699]
4DE243 [IB_Services.pas][IB_Services][TpFIBServerProperties.Create][1032]
42D984 [classes.pas][Classes][CreateComponent][6503]
42DBB9 [classes.pas][Classes][TReader.ReadComponent][6549]
42CF55 [classes.pas][Classes][TReader.EndOfList][6170]

Der Block wird momentan für eine Objektklasse benutzt TStringList

The allocation number is: 3791

Aktueller Speicherauszug von 256 Bytes, beginnend ab Zeigeradresse 7FE50E40:
F0 49 42 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 18 DF 4D 00 50 68 F6 7F 20 DF 4D 00 50 68 F6 7F 96 41 75 7D 10 D1 5E 00
10 D1 5E 00 10 D1 5E 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
E1 0E 00 00 1A 30 40 00 93 46 40 00 5A 4A 40 00 0A 8B 44 00 10 2F 43 00 FD 55 45 00 7C C4 4F 00
24 AF 4E 00 84 D9 42 00 B9 DB 42 00 36 30 40 00 B1 46 40 00 A5 4A 40 00 D0 90 42 00 F7 46 40 00
48 68 41 00 93 57 45 00 A5 4A 40 00 8F C8 4F 00 CF B0 4E 00 40 00 00 00 98 1F 44 00 75 54 84 85
10 CE 5E 00 10 D1 5E 00 10 D1 5E 00 10 D1 5E 00 10 D1 5E 00 10 D1 5E 00 10 D1 5E 00 10 D1 5E 00
10 D1 5E 00 10 D1 5E 00 10 D1 5E 00 10 D1 5E 00 10 D1 5E 00 10 D1 5E 00 10 D1 5E 00 10 D1 5E 00
ð  I B . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . ß  M . P h ö       ß  M . P h ö    –  A u }  . Ñ  ^  .
. Ñ  ^  . . Ñ  ^  . . . . . . . . . . . . . . . . . . . . . . . . .
á  . . . . 0  @  . “  F @  . Z J @  . . ‹  D . . /  C . ý  U E . |  Ä  O .
$  ¯  N . „  Ù  B . ¹  Û  B . 6  0  @  . ±  F @  . ¥  J @  . Р   B . ÷  F @  .
H h A . “  W E . ¥  J @  .   È  O . Ï  °  N . @  . . . ˜  . D . u T „  …
. Π ^  . . Ñ  ^  . . Ñ  ^  . . Ñ  ^  . . Ñ  ^  . . Ñ  ^  . . Ñ  ^  . . Ñ  ^  .
. Ñ  ^  . . Ñ  ^  . . Ñ  ^  . . Ñ  ^  . . Ñ  ^  . . Ñ  ^  . . Ñ  ^  . . Ñ  ^  .

--------------------------------2009/8/10 21:26:11--------------------------------
Diese Anwendung hat Speicher verloren. Die Größen von kleinen Speicherblöcken, die verlorengegangen sind, betragen (ausgenommen erwartete Speicherlecks, die durch Zeiger registriert wurden):

53 - 68 Bytes: TStringList x 1
das ist das Log-File vom richtigen Programm, ich kann nicht erkennen wo die TStringlist stehen soll.

Bis bald Chemiker

himitsu 10. Aug 2009 20:36

Re: Memory Leak in einer TStringList
 
lädst du irgendwo etwas mit TReader oder einem seiner Nachfahren?

bzw. läßt sich irgendwo die rückverfolgung des Aufrufstacks höhersetzen?
(hier werden ja anscheinend nur maximal 10 Sprünge zurückverfolgt)

Chemiker 10. Aug 2009 20:46

Re: Memory Leak in einer TStringList
 
Hallo,

ich lade nichts mit TReader, es sei denn das eine Fremdkomponente das macht.

Bis bald Chemiker

himitsu 10. Aug 2009 20:50

Re: Memory Leak in einer TStringList
 
vielleicht irgendeine Deserialisierung im Zusammenhang mit diesem TpFIBServerProperties?

Chemiker 10. Aug 2009 21:28

Re: Memory Leak in einer TStringList
 
Hallo himitsu,

ich kann nichts erkennen. Ich glaube ich werde jede einzelne TStringList im Project raussuchen und nachsehen ob sie ordentlich frei gegeben worden ist.

Die Anwendung läuft jetzt seit ca. 4 Monaten Tag und Nacht, bis jetzt scheint das Memory Leak nicht sonderlich zu stören, aber trotzdem möchte ich den Fehler finden und korrigieren.

Bis bald Chemiker

himitsu 10. Aug 2009 21:50

Re: Memory Leak in einer TStringList
 
wenn diese Stringlist nur einmal (z.B. bei Programmstart) erzeugt wird, dann fällt es ja nicht so auf, vorallem da WinNT ja nach Programmende die Programmresourcen wieder freigibt (in Win9x hätte sich das angesamelt)

alzaimar 11. Aug 2009 16:45

Re: Memory Leak in einer TStringList
 
Zitat:

Zitat von Chemiker
ich kann nichts erkennen.

Was steht denn in der Datei "IB_Services.pas" in Zeile 699, also im Konstruktor der Klasse TpFIBCustomService?

hoika 11. Aug 2009 17:37

Re: Memory Leak in einer TStringList
 
Hallo,

da steht

Delphi-Quellcode:
FParams := TStringList.Create;
Kann es sein, dass die sowas schreibst wie

Delphi-Quellcode:
.Params:= MyStringList
?, statt etwas per Add oder Assign (?) zu setzen


Heiko

alzaimar 12. Aug 2009 08:12

Re: Memory Leak in einer TStringList
 
Das wäre aber ein schwerer Fehler in der IB_Services.Pas.

Schau Dir den Setter der Eigenschaft 'Params' bzw. stelle sicher, das dort 'Assign' aufrufst.
Delphi-Quellcode:
Procedure TpFIBCustomService.SetParams(Const Value : TStrings);
Begin
  If Not Assigned (FParams) Then   // Derzeit überflüssig, aber sischer-is-sischer
    FParams := TStringList.Create;
  If Assigned (Value) Then
    FParams.Assign (Value)
  Else
    FParams.Clear // Oder Exceptionbehandlung, das Value nicht NIL sein darf
End;

dataspider 12. Aug 2009 08:54

Re: Memory Leak in einer TStringList
 
Hi,

@Chemiker
Hast du eine ältere Version von FibPlus?

In der Version 6.9.5 [EDIT]Zahlendreher[/EDIT] gab es nämlich ein Fix: (Potential memory leak on using services has been fixed.)

Frank

hoika 12. Aug 2009 09:41

Re: Memory Leak in einer TStringList
 
Hallo,

also in der 6.8.5 steht Assign drin.


Heiko

Chemiker 12. Aug 2009 20:26

Re: Memory Leak in einer TStringList
 
Hallo,

@hoika: Liegt das Problem an FibPlus, oder an meinem Programm? Ich werde aus Deinem Beitrag #23 nicht ganz schlau.

@alzaimar: Wie bereits hoika geschrieben hat steht dort:
Delphi-Quellcode:
procedure TpFIBCustomService.SetParams(const Value: TStrings);
begin
  FParams.Assign(Value);
end;
@dataspider: die Version 6.8.5 ist im Einsatz. Werde das morgen mal auf einen anderen Rechner überprüfen, dort läuft die Version 6.9.5. (allerdings unter Vista).

Bis bald Chemiker

hoika 13. Aug 2009 07:20

Re: Memory Leak in einer TStringList
 
Haölo,

ich denke, liegt an dir ;)
Ich nutze auch die 6.8.5, allerdings nicht als Service.
MemCheck zeigt mir keine Fehler.

Aber sag Bescheid, einen Dienst muss ich demnächst auch machen.


Heiko

alzaimar 13. Aug 2009 08:36

Re: Memory Leak in einer TStringList
 
Wenn es nur dieses eine Leck gibt, dann erinnert mich das an die Indies, die auch so ein Leck haben, nur weil sie zu faul sind, beim Programmende ordendlich aufzuräumen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:50 Uhr.

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