AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Wie kann man ein "halbes" Memory-Leak finden?

Wie kann man ein "halbes" Memory-Leak finden?

Ein Thema von Phoenix · begonnen am 28. Mai 2008 · letzter Beitrag vom 31. Mai 2008
Antwort Antwort
Seite 2 von 4     12 34   
Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.604 Beiträge
 
#11

Re: Wie kann man ein "halbes" Memory-Leak finden?

  Alt 28. Mai 2008, 16:36
Genau das wollte ich eigentlich nicht lesen
Sebastian Gingter
Phoenix - 不死鳥
Mein Blog: http://gingter.org
  Mit Zitat antworten Zitat
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.753 Beiträge
 
Delphi 11 Alexandria
 
#12

Re: Wie kann man ein "halbes" Memory-Leak finden?

  Alt 28. Mai 2008, 16:37
Ich habe aber bestimmt unrecht Ist fast immer so, vor allem wenn ich mir absolut sicher bin, daß ich recht habe

Sherlock
Oliver
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#13

Re: Wie kann man ein "halbes" Memory-Leak finden?

  Alt 28. Mai 2008, 16:59
Ich mache z.B. Folgendes:
1. Jedes Objekt einer Klasse bekommt eine bestimmte ID (Zähler), die ID ist ein privates Feld.
2. Ich schreibe die ID in eine TList (oder das Objekt selbst, egal).
3. Im Destruktur entferne ich das Object/ID wieder aus dieser Liste.
4. Im IOnitikalization-Abschnitt der Unit wird die Liste instantiiert
5. Im Finalization-Abschnitt schaue ich nach, ob die Liste leer ist....
6. Wenn die Liste nicht leer ist, dann ....
7. Nehme ich mir die erste ID, die nicht freigegeben wurde und ...
8. Setze nun im Konstruktor einen Breakpoint mit der Bedingung (ID=12345, 12345=ID des nicht freigegeben Objektes)
9. Nun warte ich, bis dieses Objekt erzeugt wird und kann im Stack nachschauen, wieso ich so blöd war, und dieses Objekt nicht freigegeben habe.
10. Das Das mache ich bis die Liste leer ist. FERTIG.

So, damit Du das aber nicht für jede Klasse machen musst, patchst Du einfach die Classes.Pas (da ist doch TObject drin, oder?) und bohrst kurz mal TObjects.Create und TObjects.Destroy auf.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#14

Re: Wie kann man ein "halbes" Memory-Leak finden?

  Alt 28. Mai 2008, 17:41
Das scheint mir eher ein Speicher Fragmentierungsproblem zu sein.
Die Anwendung fragt beim Memory Manager nach Speicher in mehr oder weniger kleinen Blöcken.
Der Memory Manager holt sich den Speicher in grossen Blöcken (~ 1 MByte) mit VirtualAlloc() bei Windows
und verwaltet diese dann, indem er kleinere Blöcke der Anwendung zuteilt.

Angenommen, du hast folgenden Code:
Delphi-Quellcode:
for i := 1 to 1000 do
   astring := astring +'*';
dann wird der String immer länger und benötigt immer mehr Speicher.
Es wird immer wieder neuer Speicher angefordert und es bleiben jede Menge unbenützte Speicherblöckchen zurück.
Ein intelligenter Memory-Manager könnte die kleinen Blöckchen zu einem grossen Block zusammenfassen (Stichwort: Garbage collection ).
Der Delphi MM ist nicht so schlau und gibt Blöcke, die er in kleine Häpchen aufgeteilt hat nicht mehr an Windows zurück.

Man sollete also:
* Objekte in umgekehrter Reihenfolge freigeben als wie man sie erzeugt hat
* AnsiStrings und dynamische Arrays nicht Elementweise vergrössern
* statt dynamische Arrays, die häufig in der Grösse verändert werden die Klasse TList und deren Nachkommen verwenden.

Delphi-Quellcode:
// das wäre ein Beispiel, wie man es nicht machen sollte
SetLength(dynamic_array, Length(dynamic_array)+1);
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: Wie kann man ein "halbes" Memory-Leak finden?

  Alt 28. Mai 2008, 23:31
Und sicher, daß dieses MML im Memorymanager liegt?

Wenn ich z.B. am Memorymanager vorbei direkt bei Windows Speicher anfordere, dann gibt es nette Nebenwirkungen.

Viele MML-Test schlagen dann fehl, da sie vorzugsweise nur den Memorymanager überwachen, aber z.B. nicht VirtualAlloc ... wobei dann zwar ein MML vorhanden sein kann, aber es nicht erkannt wird.


Und dann gibt es noch das Problem der Speicherdefragmentierung ... da hat der Memorymanager dann viel Speicher zur Verwaltung angefordert, aber es wird nur ein Teil vom Programm verwendet ... der Rest liegt ungenutzt rum, was aber laut Definition kein Speicherleak ist.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#16

Re: Wie kann man ein "halbes" Memory-Leak finden?

  Alt 29. Mai 2008, 00:11
Zitat von Phoenix:
Hast Du irgendwie einen Ansatz, was für ein Aufwand das wäre sowas zu schreiben? Insbesondere wenn man (wie ich) keinen Plan davon hat wie man sich in das Memory-Management einhängt?
Nein, leider nicht. Allerdings sollte in der Hilfe etwas zu TMemoryManager (oder so ähnlich) stehen - das Ding ist ein Record mit mehreren Funktionszeigern, die Delphi intern für GetMem, FreeMem usw verwendet.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: Wie kann man ein "halbes" Memory-Leak finden?

  Alt 29. Mai 2008, 01:48
und um eigene Funktionen zu setzen:

- mit Delphi-Referenz durchsuchenGetMemoryManager die aktuellen Adressen auslesen und speichern
- mit Delphi-Referenz durchsuchenSetMemoryManager die eigenen Funktionen übergeben

und in den eigenen Funktionen dann irgendwas machen und die Aufrufe an die alten (gespeicherten) Funktionen übergeben.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
hewy

Registriert seit: 2. Aug 2006
Ort: Arni (Region Zürich) Schweiz
81 Beiträge
 
Delphi XE5 Enterprise
 
#18

Re: Wie kann man ein "halbes" Memory-Leak finden?

  Alt 29. Mai 2008, 08:50
Hallo
Benutze doch mal FastMM. Kostet nichts und bringt dich ganz sicher weiter.
Dann poste den Log, und ich sage dir in welcher Zeile was aloziert wird das nicht wieder freigegeben wird.

Und so geht es:
In Datei FastMM4Options.inc von FastMM folgende Flags setzen:
{$define CheckHeapForCorruption}
{$define ClearLogFileOnStartup}
{$define EnableMemoryLeakReporting}

Im Delphi: in der dpr deiner Applikation.
program MeinProgramm;


uses
// >>>>>> Dies muss hier an erster stelle stehen
FastMM4,
idGlobal, IdThreadSafe, // for FastMM: registering expected leaks

Forms,
SysUtils,
Windows,
Classes,
Registry,



Im Delphi die Option vom Linker Include TD32 debug Info setzen und vollständig kompilieren. Die Applikation in der Delphi Umgebung betreiben, ein bischen überal hinklicken. Beim beenden wird eine Log Datei geschrieben.

Übrigens Memory leaks gibt es keine halben. In deinem falle handelt es sich ebenfalls um ein ganzes.
Heinrich Wyssen
  Mit Zitat antworten Zitat
Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.604 Beiträge
 
#19

Re: Wie kann man ein "halbes" Memory-Leak finden?

  Alt 29. Mai 2008, 08:51
Zitat von shmia:
Das scheint mir eher ein Speicher Fragmentierungsproblem zu sein.
[...]
Man sollete also:
[..]
* AnsiStrings und dynamische Arrays nicht Elementweise vergrössern
* statt dynamische Arrays, die häufig in der Grösse verändert werden die Klasse TList und deren Nachkommen verwenden.

Delphi-Quellcode:
// das wäre ein Beispiel, wie man es nicht machen sollte
SetLength(dynamic_array, Length(dynamic_array)+1);
Oha.
Davon wird (in diesem Fall leider) an manchen Stellen exzessiver Gebrauch gemacht.

Also sollte ich vielleicht erstmal hier auf TList umstellen... Puuh.. das wird viel Arbeit.

Edit Nachtrag:
Nochmal @Hewy: Es gibt kein Leak. Alle Objekte, die irgendwann mal allokiert werden, werden auch wieder Freigegeben.
Blöderweise halt erst beim Beenden der Anwendung und nicht schon dann, wenn sie einfach nicht mehr benötigt werden.

Ergo: Es wird alles aufgeräumt. Sämtliche Tools wie FastMM & Eurekalog können kein Leak entdecken, weil eben im technischen Sinne keines existiert. Und ich denke nicht, dass FastMM meinen Code analysiert und mir aufzeigt, wo ich ein Objekt optimalerweise freigeben müsste, damit das nicht unnötig rumliegt.

Man.. ich würd mir so sehr eine Garbage-Collection wünschen.

Edit Nachtrag 2:

Würde sich das Fragmentierungs-Problem mit dem FastMM lösen?
Sebastian Gingter
Phoenix - 不死鳥
Mein Blog: http://gingter.org
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#20

Re: Wie kann man ein "halbes" Memory-Leak finden?

  Alt 29. Mai 2008, 10:20
Zitat von Phoenix:
Würde sich das Fragmentierungs-Problem mit dem FastMM lösen?
Ein wenig. Verwendest Du COM? Ich hatte einmal mit einer komplexen COM-Library ähnliche Probleme und sie nicht in den Griff bekommen.

[klugscheiss]
Du kannst Deine dynamischen Arrays ruhig behalten, aber hier sieht man mal wieder, wie gut ordendliche OOP ist: So ein Array gehört gekapselt, damit man logische Operationen ('Einfügen eines Datensatzes mit eventueller Vergrößerung des Speichers') zentral implementieren kann. Dann hättest du einfach die Strategie des Speichervergrößerns ändern können. So musst du leider durch Deinen gesamten Code.
[/klugscheiss]
Das nicht als Verarsche für Dich, sondern als Beispiel, wieso OOP und Zentralisierung so wichtig ist.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 16:41 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