AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Verständnisfrage Memory-Leak einfacher String
Thema durchsuchen
Ansicht
Themen-Optionen

Verständnisfrage Memory-Leak einfacher String

Ein Thema von Pfoto · begonnen am 9. Sep 2008 · letzter Beitrag vom 9. Sep 2008
Antwort Antwort
Pfoto

Registriert seit: 26. Aug 2005
Ort: Daun
541 Beiträge
 
Turbo Delphi für Win32
 
#1

Verständnisfrage Memory-Leak einfacher String

  Alt 9. Sep 2008, 10:21
Hallo zusammen,

ich habe mir angewöhnt immer mit
ReportMemoryLeaksOnShutdown := (DebugHook <> 0); zu arbeiten.

Neuerdings bekomme ich nach Programmende manchmal, also unter
noch ungeklärten Bedinungen die Meldung, dass ein kleines
Speicherloch vorhanden ist und die Ergänzung "String".

Ich dachte immer, die Freigabe von Strings würde Delphi automatisch
erledingen, deshalb kann ich mir nicht erklären, wieso diese
Meldung überhaupt angezeigt wird (und ich habe auch keine Hoffung,
dieses Leck zu finden, denn mir fehlt einfach der Ansatzspunkt).



Könnt ihr mir da genaueres zu sagen?

Dank und Gruß
Jürgen
Jürgen Höfs
  Mit Zitat antworten Zitat
Benutzerbild von littleDave
littleDave

Registriert seit: 27. Apr 2006
Ort: München
556 Beiträge
 
Delphi 7 Professional
 
#2

Re: Verständnisfrage Memory-Leak einfacher String

  Alt 9. Sep 2008, 12:06
Delphi gibt die Strings an sich schon frei, sobald du aber mit Pointern auf Strings arbeitest, wirds haarig.

Mit folgendem Code bekommt man leicht ein Memory-Leak, obwohl man im OnDestroy die Pointer wieder freigibt.
Delphi-Quellcode:
var
  aList : TList;

procedure TForm1.FormCreate(Sender: TObject);
var p: PString;
    i: integer;
begin
  aList := TList.Create;

  for i:=0 to 10 do
  begin
    New(p);
    p^ := 'Test - 123';
    aList.Add(p);
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
var p: PString;
    i: integer;
begin
  for i:=0 to aList.Count-1 do
  begin
    p := aList[i];
    // mit Dispose wird zwar der Pointer wieder freigegeben, aber
    // der Inhalt ('Test - 123') vom Anfang wird nicht wieder
    // Freigegeben.
    Dispose(p);
  end;
  aList.Clear;
  aList.Free;
end;
Das Memory-Leak kann man umgehen, wenn man z.B. vor dem Dispose(p) in Zeile 28 folgende Zeile einfügt
Delphi-Quellcode:
{ ... }
    p^ := ''; // hiermit wird der String an sich wieder freigegeben
    Dispose(p);
  end;
{ ... }
Allgemein hat Delphi auch eine Funktion dafür: Finalize();
Aus der Delphi-Hilfe:
Zitat:
procedure Finalize(var V [; Count: Integer] );

Beschreibung
Finalize sollte nur in Delphi-Quelltext verwendet werden, in dem eine dynamisch erstellte Variable nicht mit der Prozedur Dispose freigegeben wird. Der von dynamische Arrays belegte Speicher kann mit der Prozedur Dispose nicht freigegeben werden. Dynamische Arrays müssen dazu an Finalize übergeben werden.
Beim Freigeben von globalen Variablen, lokalen Variablen, Objekten und dynamischen Variablen mit Dispose generiert der Compiler Programmcode, um alle in der Variablen enthaltenen langen Strings, Varianten und Schnittstellen zusammen mit der Instanz zu finalisieren.
Wenn auf eine dynamische Variable folgende Bedingungen zutreffen
  • Die Variable wird nicht mit der Standardprozedur Dispose (sondern z.B. mit FreeMem) freigegeben.
  • Die Variable enthält lange Strings, Varianten und Schnittstellen, die nicht alle leer sind bzw. den Wert Unassigned haben
Finalize setzt einfach alle langen Strings auf einen leeren Wert und alle Varianten und Schnittstellen auf Unassigned und sorgt somit für die ordnungsgemäße Freigabe des betreffenden Speichers.
Werden mehrere Variablen in einem zusammenhängenden Speicherblock freigegeben (z.B. ein dynamisches String-Array), kann der optionale Parameter Count angegeben werden, um alle Variablen in einer Operation zu deinitialisieren.
Enthält die als Parameter an Finalize übergebene Variable keine langen Strings, Varianten oder Schnittstelle entfernt der Compiler den Aufruf und generiert keinen Code.
Das ist jetzt nur eine Beschreibung, wie mir Strings Memory-Leaks entstehen können.
Jabber: littleDave@jabber.org
in case of 1 is 0 do external raise while in public class of object array else repeat until 1 is 0
  Mit Zitat antworten Zitat
Pfoto

Registriert seit: 26. Aug 2005
Ort: Daun
541 Beiträge
 
Turbo Delphi für Win32
 
#3

Re: Verständnisfrage Memory-Leak einfacher String

  Alt 9. Sep 2008, 12:14
Danke für Deine ausführliche Beschreibung,
habe auf jeden Fall was dazugelernt.

Ich arbeite zwar selbst nicht mit Pointern auf Strings,
aber vielleicht ist eine meiner Fremd-Komponenten die
Ursache. Schade, dass ich es bis jetzt nicht gezielt
reproduzieren konnte, dann wäre ich einen Schritt weiter.

Gruß
Jürgen
Jürgen Höfs
  Mit Zitat antworten Zitat
hanspeter

Registriert seit: 26. Jul 2003
Ort: Leipzig
1.350 Beiträge
 
Delphi XE2 Professional
 
#4

Re: Verständnisfrage Memory-Leak einfacher String

  Alt 9. Sep 2008, 13:21
Zitat von Pfoto:
Danke für Deine ausführliche Beschreibung,
habe auf jeden Fall was dazugelernt.

Ich arbeite zwar selbst nicht mit Pointern auf Strings,
aber vielleicht ist eine meiner Fremd-Komponenten die
Ursache. Schade, dass ich es bis jetzt nicht gezielt
reproduzieren konnte, dann wäre ich einen Schritt weiter.

Gruß
Jürgen
VST - virtualStringTree ist ein üblicher Kandidat für diese Art von Speicherleaks.
Ist aber egal, da der Speicher mit Programmende ohnehin freigegeben wird.

Gruß Peter
  Mit Zitat antworten Zitat
Tyrael Y.

Registriert seit: 28. Jul 2003
Ort: Stuttgart
1.093 Beiträge
 
Delphi 2007 Professional
 
#5

Re: Verständnisfrage Memory-Leak einfacher String

  Alt 9. Sep 2008, 13:41
Zitat von hanspeter:

VST - virtualStringTree ist ein üblicher Kandidat für diese Art von Speicherleaks.
Ist aber egal, da der Speicher mit Programmende ohnehin freigegeben wird.

Gruß Peter
Nicht VST ist der schlimme Finger dabei, sondern derjenige, der es benutzt.

Hat man z.B. als Datenstruktur einen Record mit Strings als Felder, dann muss man diese Strings bei der Freigabe auf einen Leerstring setzen.
Levent Yildirim
Erzeugung von Icons aus Bildern:IconLev
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#6

Re: Verständnisfrage Memory-Leak einfacher String

  Alt 9. Sep 2008, 14:14
Hallo,
Zitat von Tyrael Y.:
Hat man z.B. als Datenstruktur einen Record mit Strings als Felder, dann muss man diese Strings bei der Freigabe auf einen Leerstring setzen.
der korrekte Weg hierfür wäre wohl Delphi-Referenz durchsuchenFinalize().

Gruß
xaromz
I am a leaf on the wind - watch how I soar
  Mit Zitat antworten Zitat
Tyrael Y.

Registriert seit: 28. Jul 2003
Ort: Stuttgart
1.093 Beiträge
 
Delphi 2007 Professional
 
#7

Re: Verständnisfrage Memory-Leak einfacher String

  Alt 9. Sep 2008, 14:18
Ok für dynamische Arrays, was ein String ja auch ist, ist dies vielleicht doch die bessere Wahl.
Ich habe es ehrlich gesagt bisher auf einen Leerstring gesetzt und hatte auch keine Leaks mehr.
Levent Yildirim
Erzeugung von Icons aus Bildern:IconLev
  Mit Zitat antworten Zitat
Benutzerbild von littleDave
littleDave

Registriert seit: 27. Apr 2006
Ort: München
556 Beiträge
 
Delphi 7 Professional
 
#8

Re: Verständnisfrage Memory-Leak einfacher String

  Alt 9. Sep 2008, 14:18
Zitat von xaromz:
der korrekte Weg hierfür wäre wohl Delphi-Referenz durchsuchenFinalize().
Siehe mein Post (#2)
Jabber: littleDave@jabber.org
in case of 1 is 0 do external raise while in public class of object array else repeat until 1 is 0
  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 07:26 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