Autor Beitrag
P_G
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 75

Win XP
Delphi 7 / 8 Enterprise
BeitragVerfasst: Di 22.07.08 11:51 
Hallo zusammen,

Ich habe von www.Delphi3000.com einen simplen Code getestet, um Speicherlecks aufzuspüren. Dabei bin ich auf ein merkwürdiges Verhalten beim Einsatz von IntToStr gestoßen.

Der Code sieht folgendermaßen aus:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure TForm1.Button1Click(Sender: TObject);
var
  Point1,Point2:Integer;
  IsLeak:Boolean;
  tmpInt: string;
begin
 Point1:=AllocMemSize; //Hold Allocated Memory size

 tmpInt := IntToStr(10); // Ergibt ein Speicherleck
// tmpInt := '10';            // Ergibt kein Speicherleck

 Point2:=AllocMemSize-Point1; //Get the differrent of                       //allocated memory size
    //between two Points of code

  if Point2<>0 then
    ShowMessage('We have ' + IntToStr(Point2)+' byte as memory leak ')
end;


Schreibe ich tmpInt := IntToStr(10) ergibt sich ein Speicherleck von 12 byte.
Kommentiere ich diese Zeile hinaus und weise dem String über tmpInt := '10' einen Wert zu, kommt es zu keinem Speicherleck.
Hat jemand eine Erklärung dazu?

Gruß, P_G
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Di 22.07.08 11:53 
Mein Tipp: Wenn Du den String direkt zuweist, optimiert der Compiler das weg, weil er "weiß", dass der String nicht mehr benutzt wird. Benutzt Du eine Funktion, kann es sein, dass diese Seiteneffekte hat und die Zeile wird nicht wegoptimiert.

Warum es ein Speicherleck sein soll, wenn eine Variable Speicher verbraucht, leuchtet mir aber nicht ein. Irgendwo müssen die Informationen ja gespeichert werden. :nixweiss:

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Di 22.07.08 12:43 
Da habe ich noch eine Ergänzung zu Christians Aussage. Wenn der Compiler diese Zeile nicht wegoptimiert, dann ist es richtig. Irgendwo müssen die Informationen ja abgespeichert werden. ABER es ist kein Speicherloch. Diese Messmethode berücksichtigt nämlich leider nicht die Eigenarten von Strings. Es gibt dynamische und statische (konstante) Strings.

Konstante Strings sind etwas wie 'Blahh'. Das wird als Daten hinter die Methode in gepackt. Diese Texte sind als dauerhaft vorhanden. Beim Zuweisen wird diese Konstante lediglich deinem String zugewiesen.

Dynamische Strings (wie bei IntToStr) verfügen über eine Referenzzählung. Wird ein String benutzt wird sie erhöht. Wird er nicht mehr benutzt wird sie verringert. Ist sie bei 0 angelangt wird der String gelöscht. Das irritierende an dieser Zählung ist aber, dass sie am Ende der Methode erst verringert wird. Und das macht der Kompiler ganz automatisch. Und vor allem wirklich als Letztes in der Methode. DU kannst in einer Methode KEINEN Code schreiben der nach dieser Stringfreigabe ausgeführt wird. Entsprechend existiert der String zum Zeitpunkt der Messung noch. Erst wenn die Methode beendet wurde wird der String gelöscht. Oder aber du weißt dem String selber '' (leerstring) zu. Dann wird er auch freigegeben. Aber das selber zu machen ist doppelt gemoppelt, da das am Ende der Methode sowieso passiert. Also mehr Arbeit für den Rechner als nötig.

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
P_G Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 75

Win XP
Delphi 7 / 8 Enterprise
BeitragVerfasst: Di 22.07.08 13:36 
user profile iconLossy eX hat folgendes geschrieben:
Oder aber du weißt dem String selber '' (leerstring) zu. Dann wird er auch freigegeben. Aber das selber zu machen ist doppelt gemoppelt, da das am Ende der Methode sowieso passiert. Also mehr Arbeit für den Rechner als nötig.


Ist mir auch aufgefallen (wenn man beide Zeilen in der obigen Reihenfolge drinläßt ergibt sich nämlich auch kein Problem).
Die Erklärung leuchtet mir ein - auch wenn das leider heißt, daß der Code als Speicherleckmanager nicht viel taugt.

Danke und Gruß, P_G
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Di 22.07.08 13:38 
Besorg Dir einfach FastMM, dann hast Du deinen Speichleck-Aufspür-O-Mat. Und 'etwas' schneller werden deine Anwendungen auch.

_________________
Na denn, dann. Bis dann, denn.
Fabian E.
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 554

Windows 7 Ultimate
Visual Studio 2008 Pro, Visual Studion 2010 Ultimate
BeitragVerfasst: Di 22.07.08 14:40 
user profile iconalzaimar hat folgendes geschrieben:
Besorg Dir einfach FastMM, dann hast Du deinen Speichleck-Aufspür-O-Mat. Und 'etwas' schneller werden deine Anwendungen auch.

Bei mir grade ne ganze Sekunde :) ;) Klingt für manche vielleicht nicht viel, ist es aber :)