AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Memory Leak: Ursache finden

Ein Thema von Jazzman_Marburg · begonnen am 16. Feb 2013 · letzter Beitrag vom 1. Mär 2013
Antwort Antwort
Benutzerbild von sx2008
sx2008

Registriert seit: 15. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#1

AW: Memory Leak: Ursache finden

  Alt 16. Feb 2013, 16:52
Ein kleiner Tipp: durchsuche den gesamten Sourcecode nach "destructor Destroy; "; wenn irgendwo der Zusatz "override; " fehlt, dann ist das ein potentielles Speicherleck.

Zusätzlich kann man noch nach "destructor T" suchen und prüfen ob in jedem Destruktor auch das inherrited aufgerufen wurde.

Geändert von sx2008 (16. Feb 2013 um 16:54 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Jazzman_Marburg
Jazzman_Marburg

Registriert seit: 2. Aug 2004
359 Beiträge
 
#2

AW: Memory Leak: Ursache finden

  Alt 16. Feb 2013, 17:12
Ein kleiner Tipp: durchsuche den gesamten Sourcecode nach "destructor Destroy; "; wenn irgendwo der Zusatz "override; " fehlt, dann ist das ein potentielles Speicherleck.

Zusätzlich kann man noch nach "destructor T" suchen und prüfen ob in jedem Destruktor auch das inherrited aufgerufen wurde.
Ein sehr guter Tipp -- leider kein Destructor ohne override, und in jedem Destructor ist stets ein "inherited Destroy;"
Ich dachte schon, dass muß es sein... Dennoch ein guter Tipp!

[...] Warum? MadExcept arbeitet ja nicht nach dem Zufallsprinzip. Also mal gucken: Wie ist fHfgkFarbe definiert? Ist es eine property, eine private oder was sonst? Wird das vielleicht irgendwo vorher auf nil gesetzt?
Diesen Hinweis verstehe ich nicht, ich sagte ja, bei fHfgkFarbe handelt es sich um ein Array of Integer -- und ja, es ist ein private Klassenvariable. Ein Nil ist nirgends zu finden.

Man kann zuerst einmal auch manuell den Code durchscannen, sofern es sich noch um kein allzu umfangreiches Projekt handelt.
Such einfach mal nach ".Create" und "GetMem"/"New" o.Ä.
Überprüfe anschließend, ob letzendlich alles allozierte auch zu 100% freigegeben wird.
Jou -- das war mein Vorgehen, bevor ich das hier postete.

Es sind nicht allzu viele Klassen und Units -- vielleicht mal eine kleine Pause -- und dann mit Kaffee...

Vielen Dank euch allen!

Jazzman
--- Delphi XE Starter, Windows 8 ---
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.492 Beiträge
 
Delphi 7 Enterprise
 
#3

AW: Memory Leak: Ursache finden

  Alt 16. Feb 2013, 17:25
Versuch mal im destructor der Klasse ein SetLength(fHfgkFarbe, 0)
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
Benutzerbild von Jazzman_Marburg
Jazzman_Marburg

Registriert seit: 2. Aug 2004
359 Beiträge
 
#4

AW: Memory Leak: Ursache finden

  Alt 16. Feb 2013, 18:32
Versuch mal im destructor der Klasse ein SetLength(fHfgkFarbe, 0)
Keinerlei Wirkung -- ReportMemoryLeak ("37-44 Bytes: Unknown x 1") unverändert.
Delphi-Quellcode:
destructor TPaletto.Destroy;
begin

  inherited Destroy;
  SetLength(fHfgkFarbe, 0);

end;
Danke!
--- Delphi XE Starter, Windows 8 ---
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.779 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Memory Leak: Ursache finden

  Alt 16. Feb 2013, 18:35
Versuch mal im destructor der Klasse ein SetLength(fHfgkFarbe, 0)
Keinerlei Wirkung -- ReportMemoryLeak ("37-44 Bytes: Unknown x 1") unverändert.
Delphi-Quellcode:
destructor TPaletto.Destroy;
begin

 
  SetLength(fHfgkFarbe, 0);
  inherited Destroy;
end;
Danke!
.. und wenn Du inherited Destroy als letztes aufrufst?

Grüße
Klaus
Klaus
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.492 Beiträge
 
Delphi 7 Enterprise
 
#6

AW: Memory Leak: Ursache finden

  Alt 16. Feb 2013, 18:38
Und so?
Delphi-Quellcode:
destructor TPaletto.Destroy;
begin
  SetLength(fHfgkFarbe, 0);
  fHfgkFarbe := nil;
  inherited Destroy;
end;
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: Memory Leak: Ursache finden

  Alt 16. Feb 2013, 18:52
Ein Array (dynamisch oder statisch) muss nicht freigeben werden. Das ist also mal nicht der Grund.

Unknown (ganz alleine für sich) ist auch eher ein Hinweis auf einen mit GetMem /AllocMem allozierten Speicher-Bereich.

Sourcen möchtest du aber wohl hier nicht reinstellen?

Dann wird es schwierig, denn so ist das ein Blindflug
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von Jazzman_Marburg
Jazzman_Marburg

Registriert seit: 2. Aug 2004
359 Beiträge
 
#8

AW: Memory Leak: Ursache finden

  Alt 16. Feb 2013, 21:22
Und so?
Delphi-Quellcode:
destructor TPaletto.Destroy;
begin
  SetLength(fHfgkFarbe, 0);
  fHfgkFarbe := nil;
  inherited Destroy;
end;
Dito - exakt der selbe Leak-Report.

[...]
Unknown (ganz alleine für sich) ist auch eher ein Hinweis auf einen mit GetMem /AllocMem allozierten Speicher-Bereich.

Sourcen möchtest du aber wohl hier nicht reinstellen?

Dann wird es schwierig, denn so ist das ein Blindflug
Ein explizites GetMem /AllocMem nutze ich nicht.

Sourcen wären im Prinzip überhaupt kein Problem -- aber es ist doch einiges an Code, und das wäre wirklich nicht ok, euch meinen Fehler im meinem Code suchen zu lassen. Sehr lieb!

Ich werde morgen einfach mal eine große Auskommentierungsaktion starten und mal systematisch rang gehen.

Ich bin nur ein wenig enttäuscht von MadExcept, so dass es mir wirklich gar kein Hinweis geben konnte. Ist technisch aber sicher auch nicht ganz einfach.

Vielen Dank an alle - super Truppe

Gruß
Jazzman
--- Delphi XE Starter, Windows 8 ---
  Mit Zitat antworten Zitat
EgonHugeist

Registriert seit: 17. Sep 2011
187 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#9

AW: Memory Leak: Ursache finden

  Alt 16. Feb 2013, 22:20
StrNew(), ReallocMem() ???

Ist dein Project irgendwie FPC portable? Hier ist FPC Meilen vorraus mit deren HeapTracing. Hier kann man fast ganz exakt festsetellen, wo die MemLeaks "offen" bleiben und deren Ursache ergründen. Benutzt du noch eine Ansi-Delphi? Dann könnte die MemCheck.pas genauere Infos geben..
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 15. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#10

AW: Memory Leak: Ursache finden

  Alt 22. Feb 2013, 15:20
Ich bin nur ein wenig enttäuscht von MadExcept, so dass es mir wirklich gar kein Hinweis geben konnte. Ist technisch aber sicher auch nicht ganz einfach.
Je mehr man auf Klassen setzt, umso leichter wird die Fehlersuche.
Man kann z.B. dynamischee Arrays direkt in der Anwendung, der "Businesslogik", benützen.
Oder man kapselt das Array innerhalb einer Klasse und lässt nur einen kontrollierten Zugriff über die Methoden der Klasse zu.
Insbeondere sollte man Resourcen (Speicher ist auch eine Resource) immer unter die Kontrolle einer Klasse stellen.
Das heisst dann konkret, dass AllocMem und FreeMem nur im geschützten Kontext einer Klasse aufgerufen werden.
Dann testet man diese Klasse in einer isolierten Umgebung (aka Testprogramm) und kann so sicherstellen, dass die Klasse in sich keine Speicher- oder Resourcenlecks hat.

Findet man später in der Anwendung ein Speicherleck ist die Wahrscheinlichkeit höher, dass man den Klassennamen angezeigt bekommt und so gezielt suchen kann.

Manchmal bekommt man nur allgemeine Klassennamen gemeldet (z.B. TStringList x 14), dann kann man auch von TStringList abgeleitete Klassen einsetzen.
Kleines Beispiel dazu:
Delphi-Quellcode:
// Klasse zum Laden von Daten aus einer Datei
// wird zum Datenimport verwendet
// die Datei darf nicht leer sein
TImportStringList = class(TStringList)
public
  procedure LoadFromFile(const FileName: string); override;
end;

procedure TImportStringList.LoadFromFile(const FileName: string);
begin
   inherited;
   if count = 0 then
      raise EBadImportFile.CreateFmt('Datei %s ist leer', [FileName]);
end;
So schlägt man zwei Fliegen mit einer Klappe.
Man kann kleine Teile der Funktionalität an TImportStringList übertragen (prüfen ob Datei leer ist) und ausserdem bekommt man bei einem Speicherleck gezielte Info wo zu suchen ist.

Die ganzen Punkte oben gelten speziell für sehr grosse Anwendungen mit Hunderten von Units.
Bei kleinen Anwendungen braucht man nicht so viel Aufwand zu treiben.
  Mit Zitat antworten Zitat
Antwort Antwort


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:42 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