Warum benötigt SetString weniger Speicher in Delphi (mit Unicode)?

8

Dies ist Delphi 2009, also gilt Unicode.

Ich hatte Code, der Zeichenfolgen aus einem Puffer in eine StringList wie folgt geladen:

%Vor%

Aber während einiger Änderungen habe ich meine Logik so geändert, dass ich die identischen Datensätze hinzugefügt habe, aber als Strings, die separat und nicht über SetString, d. h.

, abgeleitet wurden %Vor%

Was mir aufgefallen ist, dass der Speicherverbrauch der StringList von 52 MB auf etwa 70 MB gestiegen ist. Das war ein Anstieg von über 30%.

Um zu meiner geringeren Speichernutzung zurückzukehren, musste ich SetString verwenden, um die Zeichenfolgenvariable zu erstellen, die wie folgt zu meiner StringList hinzugefügt wird:

%Vor%

Wenn Sie S und SRecord untersuchen und vergleichen, sind sie in allen Fällen genau gleich. Aber das Hinzufügen von SRecord zu MyStringList verwendet viel mehr Speicher als das Hinzufügen von S.

Weiß jemand, was passiert und warum der SetString Speicher spart?

Nachverfolgung. Ich hätte es nicht gedacht, aber ich habe nachgesehen, um sicherzugehen.

Weder:

%Vor%

noch

%Vor%

gibt den überschüssigen Speicherplatz frei. Der SetString scheint dazu erforderlich zu sein.

    
lkessler 25.09.2010, 19:04
quelle

2 Antworten

14

Wenn Sie die Zeichenfolge verketten, weist der Speichermanager mehr Speicher zu, da davon ausgegangen wird, dass Sie mehr und mehr Text hinzufügen, und weist zusätzlichen Speicherplatz für zukünftige Verkettungen zu. Auf diese Weise ist die Zuweisungsgröße der Zeichenfolge viel größer als die verwendete Größe (abhängig vom verwendeten Speichermanager). Wenn Sie SetString verwenden, ist die Zuordnungsgröße der neuen Zeichenfolge fast identisch mit der verwendeten Größe. Und wenn die SRecord-Zeichenkette ihren Gültigkeitsbereich verlässt und ihr Ref-Count Null wird, wird der von SRecord belegte Speicher freigegeben. Sie erhalten also die kleinste benötigte Zuordnungsgröße für Ihre Zeichenfolge.

    
Andreas Hausladen 25.09.2010, 20:00
quelle
-1

Versuchen Sie, den Speichermanager-Filter (Get / SetMemoryManager) zu installieren, der alle Aufrufe von GetMem / FreeMem an den Standard-Speichermanager übergibt, aber auch die Statistiken in der Warteschleife ausführt. Sie werden wahrscheinlich feststellen, dass beide Varianten im Speicherverbrauch gleich sind.

Es ist nur Speicherfragmentierung.

    
Alex 26.09.2010 08:26
quelle