AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Wie erkenne ich eigentlich ein Memory-Leak?
Thema durchsuchen
Ansicht
Themen-Optionen

Wie erkenne ich eigentlich ein Memory-Leak?

Ein Thema von pelzig · begonnen am 8. Feb 2015 · letzter Beitrag vom 9. Feb 2015
Antwort Antwort
Seite 1 von 2  1 2      
pelzig
(Gast)

n/a Beiträge
 
#1

Wie erkenne ich eigentlich ein Memory-Leak?

  Alt 8. Feb 2015, 22:40
Der Titel sollte eigentlich schon alles sagen

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
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.017 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#2

AW: Wie erkenne ich eigentlich ein Memory-Leak?

  Alt 8. Feb 2015, 22:50
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 ReportMemoryLeaksOnShutdown := True; beim beenden einen Report bekommen, ob irgendwas im Verlauf deiner Anwendung nicht korrekt freigegeben wurde.

Für erweiterte Diagnose empfiehlt sich, die FastMM4 im full debug mode laufen zu lassen - siehe dazu z.B. diesen Artikel (und in den Kommentaren dort gibts auch noch den Link zu ner Coderage Session dazu)
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
pelzig
(Gast)

n/a Beiträge
 
#3

AW: Wie erkenne ich eigentlich ein Memory-Leak?

  Alt 8. Feb 2015, 23:35
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
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.017 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#4

AW: Wie erkenne ich eigentlich ein Memory-Leak?

  Alt 8. Feb 2015, 23:45
Etwas neueres als die Delphi 7 Personal Edition will ich mir (finanziell und hobbybedingt) nicht antun.
Ok, aber FastMM nutzen geht trotzdem und ist nur zu empfehlen, auch wenn nur Hobby.

Falls ich Dich richtig verstanden habe, ist beim Beenden des Programms inzwischen NACHHER immergleich VORHER?
Nunja, aufn RAM Verbrauch im Taskmanager achten ist so ne Sache und gibt nur grobe Anhaltspunkte - aber ja, dein Programm, wenn beendet kann dem Betriebssystem kein Speicher geklaut haben, denn Windows kümmert sich drum, dass es seine Resourcen zurückbekommt.

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?
Gegenfrage, welcher Wert denn? Da gibt's nämlich mehrere. Ich verweis da mal auf eine ganz gute Erklärung.

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 nem abrollenden Seil und ner Sanduhr messen willst wie schnell du fährst
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight

Geändert von Stevie ( 8. Feb 2015 um 23:48 Uhr)
  Mit Zitat antworten Zitat
pelzig
(Gast)

n/a Beiträge
 
#5

AW: Wie erkenne ich eigentlich ein Memory-Leak?

  Alt 9. Feb 2015, 00:04
Also statt "Seilrolle und Sanduhr" irgendwie versuchen, ein älteres FastMM (auftreiben und als "GPS") einzubinden?

OK, probier' ich mal.

Vielen Dank!

MfG
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.017 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#6

AW: Wie erkenne ich eigentlich ein Memory-Leak?

  Alt 9. Feb 2015, 00:40
älteres FastMM (auftreiben und als "GPS") einzubinden?
Die aktuellste Version sollte eigentlich auch für Delphi 7 noch funktionieren.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Frank Ranis

Registriert seit: 15. Okt 2008
17 Beiträge
 
#7

AW: Wie erkenne ich eigentlich ein Memory-Leak?

  Alt 9. Feb 2015, 09:03
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.
Angehängte Dateien
Dateityp: zip Speicherleck.zip (210,8 KB, 6x aufgerufen)

Geändert von Frank Ranis ( 9. Feb 2015 um 09:26 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.078 Beiträge
 
Delphi 12 Athens
 
#8

AW: Wie erkenne ich eigentlich ein Memory-Leak?

  Alt 9. Feb 2015, 09:51
Warum ist m eine globale Variable, obwohl es nur in TForm1 benutzt wird? (das gehört als Feld ins Private der TForm1)

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 m freigegeben, wenn die Unit entladen wird
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.
FastMM bietet z.B. eine MemoryMap
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Frank Ranis

Registriert seit: 15. Okt 2008
17 Beiträge
 
#9

AW: Wie erkenne ich eigentlich ein Memory-Leak?

  Alt 9. Feb 2015, 11:02
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.
Angehängte Dateien
Dateityp: zip Speicherleck2.zip (204,1 KB, 0x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.078 Beiträge
 
Delphi 12 Athens
 
#10

AW: Wie erkenne ich eigentlich ein Memory-Leak?

  Alt 9. Feb 2015, 11:25
Delphi-Referenz durchsuchenReportMemoryLeaksOnShutdown
http://www.delphipraxis.net/183846-f...nshutdown.html

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;
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu ( 9. Feb 2015 um 11:32 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:28 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