Autor Beitrag
KidPaddle
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 351

WinXP,Linux
D7 Prof, XE7
BeitragVerfasst: Fr 10.12.04 12:42 
Ich rufe in einer Anwendung eine bestimmte Funktion mehrere Millionen mal auf. Diese Anwendung soll ca. 1.3 Mio Daten verarbeiten und aufbereiten. Diese Funktion ist einfach aufgebaut:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
function TImportObject.ReplaceChars(Data : String) : String;
begin
  Data   := StringReplace(Data, '`''''', [rfReplaceAll]);
  Data   := StringReplace(Data, '´''''', [rfReplaceAll]);
  Data   := StringReplace(Data, '//''/', [rfReplaceAll]);
  Data   := StringReplace(Data, '%%''%', [rfReplaceAll]);
  Result := StringReplace(Data, '''''''''', [rfReplaceAll]);
end;

Wie man sieht, nichts besonders. Nun scheint diese Funktion jedoch für die Rückgabe der Daten Speicher zu reservieren, der aber nicht wieder freigegeben wird. Sobald ich diese Funktion herausnehme bleibt der Verbrauch konstant, wird diese aufgerufen, so steigt der Speicherverbrauch pro 1000 Datensätze um ca. 1MB. Nach einer gewissen Zeit fängt das System an zu swappen und dann kurz daruf geht nichts mehr. Ich habe keine Ahnung, wie ich dieses Verhalten ändern kann. Das einzige wäre komplett auf PChar um zusteigen, was aber eine beträchtlichen Änderungsaufwand nachzieht.

Hat jemand einen Tip für mich, wie ich Delphi anweisen kann, nicht mehr verwendete Strings wieder freizugeben?

Gruß
KidPaddle
Udontknow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: Fr 10.12.04 12:56 
Hallo!

Also, an der String-Implementierung von Delphi liegt es nicht, ich mache das ganz ähnlich wie du, und auch mit einer 2-Gigabyte großen Textdatei, habe aber keine Probleme...

Ändere mal den Parameter-Aufruf:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
function TImportObject.ReplaceChars(const Data : String) : String;
begin
  Result := StringReplace(Data, '`''''', [rfReplaceAll]);
  Result := StringReplace(Result, '´''''', [rfReplaceAll]);
  Result := StringReplace(Result, '//''/', [rfReplaceAll]);
  Result := StringReplace(Result, '%%''%', [rfReplaceAll]);
  Result := StringReplace(Result, '''''''''', [rfReplaceAll]);
end;


Obwohl ich irgendwie bezweifle, daß es daran liegt... Gibst du vielleicht aus Versehen etwas nicht frei? Vielleicht hat es was mit der weiteren Verarbeitung des Results zu tun. Zeige bitte mal mehr Code.

Cu,
Udontknow
KidPaddle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 351

WinXP,Linux
D7 Prof, XE7
BeitragVerfasst: Fr 10.12.04 14:32 
Ich hab es geändert und wie erwartet kein Unterschied. Dann bin ich hingegangen und habe den Aufruf entfernt und das StringReplace direkt durchgeführt. Nun will mir der MemProof weis machen, das ich an einer Stelle, die im gesamten Programm nur ein einziges Mal aufgerufen wird, über 200 Speicherlecks sein sollten. Ich krieg hier die Krise.

Danke für die Antwort, wird wohl ne längere Debug-Session werden.

Gruß
KidPaddle
Udontknow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: Fr 10.12.04 14:43 
Alle Service-Packs installiert? Wie gesagt, mit etwas mehr gepostetem Code könnte man vielleicht fündig werden.

Cu,
Udontknow
KidPaddle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 351

WinXP,Linux
D7 Prof, XE7
BeitragVerfasst: Fr 10.12.04 14:50 
Ja, alle SPs installiert. Auch den Code könnte ich posten, aber um die Ursache zu finden, sind ein paar tausend Zeilen notwendig, da ich keine Eingrenzung vornehmen kann.

Ich suche mal nach einem Memory - Manager, der mir nichtfreigegebene Blöcke anzeigen kann.

Gruß
KidPaddle