![]() |
Wie erkenne ich eigentlich ein Memory-Leak?
Der Titel sollte eigentlich schon alles sagen :wink:
Ich schau' im Task-Manager VORHER nach, wieviel RAM frei ist - starte mein Programm, lasse es laufen und beende es wieder und schaue im Task-Manger NACHHER wieder nach, wieviel RAM frei ist. Wenn NACHHER=VORHER dann kein Leak? Die Frage ist wirklich ernst gemeint! MfG |
AW: Wie erkenne ich eigentlich ein Memory-Leak?
Mit der Methode wirste nix finden. Denn ein Memory leak überlebt auf nem Windows mit NT Kernel nicht mehr die Dauer eines Processes (das war mal zu 95 oder 98 Zeiten so als nen fehlerhaftes Programm mal ebend deine komplette Windows Session zerhauen hat - aber jeder Boot tat gut)
Heutzutage lebt es also nur solange, wie dein Programm auch läuft. Ist aber schlimm genug, wenn du entweder nach einigen Stunden irgendwann in deinem 32bit Programm an die Speichergrenze kommst und es dir mit Fehlern weghagelt oder dein System nichts mehr für die anderen Prozesse übrig hat. In neuen Delphi Versionen kannst du relativ einfach mit einem beherzten
Delphi-Quellcode:
beim beenden einen Report bekommen, ob irgendwas im Verlauf deiner Anwendung nicht korrekt freigegeben wurde.
ReportMemoryLeaksOnShutdown := True;
Für erweiterte Diagnose empfiehlt sich, die FastMM4 im full debug mode laufen zu lassen - siehe dazu z.B. ![]() |
AW: Wie erkenne ich eigentlich ein Memory-Leak?
Etwas neueres als die Delphi 7 Personal Edition will ich mir (finanziell und hobbybedingt) nicht antun.
Meine Programme erstellen i.A. nur das Hauptforumlar automatisch, der Rest wird bei Bedarf erzeugt. Falls ich Dich richtig verstanden habe, ist beim Beenden des Programms inzwischen NACHHER immergleich VORHER? Aber falls ich während meines Programmlaufs ein paarmal dynamisch (immer wieder) das gleiche Formular erzeuge und zerstöre, dabei im Task-Manager der RAM-Verbrauch aber nicht wieder auf den RAM-Startwert meines Programmes zurückgeht, habe ich ein Memory-Leak? Hab' ich das richtig verstanden? Danke @Stevie! MfG |
AW: Wie erkenne ich eigentlich ein Memory-Leak?
Zitat:
Zitat:
Zitat:
![]() Unterm Strich kann ich nur sagen, pack die FastMM in deine Anwendung und schau dir an, obs rummeckert. Alles andere wäre so als ob du mit ![]() |
AW: Wie erkenne ich eigentlich ein Memory-Leak?
Also statt "Seilrolle und Sanduhr" irgendwie versuchen, ein älteres FastMM (auftreiben und als "GPS") einzubinden?
OK, probier' ich mal. Vielen Dank! MfG |
AW: Wie erkenne ich eigentlich ein Memory-Leak?
Zitat:
![]() |
AW: Wie erkenne ich eigentlich ein Memory-Leak?
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
hatte öfter mal Objekte oder Speicher nicht richtig freigegeben , aber in diversen Schleifen immer wieder neu erzeugt und so ne Menge Leichen erzeugt. Nun überwache ich meinen aktuellen Speicherbedarf mit 'GetHeapStatus.TotalAllocated' . Einfach ab und an per Timer abfragen. Kann man prima in einer Statusbar, fest eingebaut im Programm, ausgeben. Quelltext und ZIP siehe unten. Button 1 erzeugt eine Integer-Matrix [100,100]. Button 2 setzt die Matrix auf [0,0] zurück. Gruß Frank
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls; type TForm1 = class(TForm) Timer1: TTimer; Button1: TButton; ListBox1: TListBox; Button2: TButton; StatusBar1: TStatusBar; procedure Timer1Timer(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; Tint_vektor=array of integer; Tint_matrix=array of Tint_vektor; var Form1: TForm1; m:tint_matrix; implementation {$R *.dfm} // Speicher-Bedarf-Abfrage procedure TForm1.Timer1Timer(Sender: TObject); var Speicherinfo:THeapStatus; begin // Aktuellen Speicherbedarf ausgeben speicherinfo:=GetHeapStatus; statusbar1.Panels[0].Text:= 'Aktueller Speicherbedarf='+ inttostr(speicherinfo.TotalAllocated)+ ' Byte'; end; // eine Integermatrix m[100,100] Global erzeugen procedure TForm1.Button1Click(Sender: TObject); var i,j:integer; s:string; begin listbox1.Clear; setlength(m,100,100); for i:=0 to 99 do begin s:=''; for j:=0 to 99 do begin m[i,j]:=i*j; s:=s+floattostr(m[i,j])+' '; end; listbox1.Items.Add(s); end; end; // die Integer-Matrix auf m[0,0] zurücksetzten procedure TForm1.Button2Click(Sender: TObject); begin setlength(m,0,0); listbox1.Clear; end; end. |
AW: Wie erkenne ich eigentlich ein Memory-Leak?
Warum ist
Delphi-Quellcode:
eine globale Variable, obwohl es nur in TForm1 benutzt wird? (das gehört als Feld ins Private der TForm1)
m
Und dann ist das kein "richtiges" Speicherleck, denn dynamische Arrays sind gemanaged und werden automatisch freigegeben, wenn sie nur noch der Herr Niemand benutzt, genauso wie Strings, Variants und Interfaces. Aber dafür gehören Variablen und eigentlich Alles nur in den Scope, in welchem sie verwendet werden. In deinem Fall wird die
Delphi-Quellcode:
freigegeben, wenn die Unit entladen wird
m
und wenn man es in TForm verschiebt, dann wird es freigegeben, wenn die Form freigegeben wird. Hier wird es schwerer, denn du müsstest den Speicher analysieren, während das Programm noch läuft, da die Speicherlecksuche bei Programmende natürlich zu spät ist. Das genannte Ding, in meiner Signatur, hat da noch mehr Probleme. :stupid: FastMM bietet z.B. eine MemoryMap |
AW: Wie erkenne ich eigentlich ein Memory-Leak?
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo himitsu,
OK das mit dem Array war jetzt ein doofes Besipiel, wollte ja nur den aktuell benutzen Speicherbedarf ausgeben. Nehmen wir das folgende Beispiel: Ich habe zwei Buttons. Mit Button3 erzeuge ich ein BMP. Mit Button4 kille ich es wieder. Drücke ich aber zwei oder noch mehr mal auf Button3, dann habe ich Bitmap-Leichen erzeugt, an die ich nicht mehr rannkomme. Das kann man dann schön an der Anzeige 'Aktueller Speicherbedarf' sehen. Ich komme dann nicht mehr auf den Speicher-Wert, den das Programm beim Starten hatte. Gruß Frank
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls; type Tint_vektor=array of integer; Tint_matrix=array of Tint_vektor; TForm1 = class(TForm) Timer1: TTimer; StatusBar1: TStatusBar; Button3: TButton; Button4: TButton; procedure Timer1Timer(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); private { Private-Deklarationen } public bmp:tbitmap; { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} // Speicher-Bedarf-Abfrage procedure TForm1.Timer1Timer(Sender: TObject); var Speicherinfo:THeapStatus; begin // Aktuellen Speicherbedarf ausgeben speicherinfo:=GetHeapStatus; statusbar1.Panels[0].Text:= 'Aktueller Speicherbedarf='+ inttostr(speicherinfo.TotalAllocated)+ ' Byte'; end; // Bitmap erzeugen procedure TForm1.Button3Click(Sender: TObject); begin bmp:=tbitmap.Create; end; // Bitmap killen procedure TForm1.Button4Click(Sender: TObject); begin if bmp<>nil then begin bmp.Free; bmp:=nil; end; end; end. |
AW: Wie erkenne ich eigentlich ein Memory-Leak?
![]() ![]() PS: .Free prüft intern bereits auf Self<>nil, bzw. aus Assigned(Self). Und deine Prüfung geht kaputt, wenn es im Free knallt und dann kein nil gesetzt wird.
Delphi-Quellcode:
procedure TForm1.Button3Click(Sender: TObject);
begin Button4Click(nil); // Aufräumfunktion aufrufen, oder direkt FreeAndNil(bmp); bmp := TBitmap.Create; end; procedure TForm1.Button4Click(Sender: TObject); begin FreeAndNil(bmp); end; procedure TForm1.Form1Close(Sender: TObject); begin Button4Click(nil); // Aufräumfunktion aufrufen, oder direkt FreeAndNil(bmp); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:51 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 by Thomas Breitkreuz