Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Speicherverbrauch eines Objektes (https://www.delphipraxis.net/33300-speicherverbrauch-eines-objektes.html)

trifid 4. Nov 2004 14:54


Speicherverbrauch eines Objektes
 
Hallo,
wie kann man den Speicherverbrauch eines Objektes ermitteln.
z.B. wieviel Bytes braucht folgende Stringliste (Daten ((Text)) und Objekt-Innereien)

Delphi-Quellcode:
var strListe : TStringList;
    Speicher : Integer;

strListe := TStringList.Create;
strListe.Add('Heute');
strListe.Add('ist');
strListe.Add('ein');
strListe.Add('schöner');
strListe.Add('Tag');

Speicher := Speicherverbrauch (strListe);
Als Ergbnis soll nicht die Summe der Buchstaben der 5 Zeilen(inkl. Zeilenumbruch) stehen
dann könnte ich ja ein
Delphi-Quellcode:
Length (strListe.Text)
verwenden.
die TStringList hat ja selber einen overhead (Datentypen, Objekte, Vererbung, etc.)
Gesucht ist die Summe von alldem.

Dax 4. Nov 2004 15:08

Re: Speicherverbrauch eines Objektes
 
Jedes Pascal-Object hat eine Methode Delphi-Referenz durchsuchenInstanceSize, die den SPeicherverbrauch des Objekts zurückgibt. Jede andere Methode (alos eine, die nicht in der Klasse definiert ist), muss fehlschlagen.

jbg 4. Nov 2004 15:14

Re: Speicherverbrauch eines Objektes
 
Für was brauchst du denn diese Information? Der belegte Speicher ist querfeldein verstreut und kein zusammenhängender Block, was z.B. ein einfaches Schreiben in einen Stream unmöglich macht (dafür gibt es ja SaveToStream).

Das dürfte hinkommen:
TStringList.InstanceSize + StrList.Capacity * SizeOf(TStringItem) + (Length(StrList[0]) + 12) + (Length(StrList[1]) + 12) + ... + (Length(StrList[Count-1]) + 12)

trifid 4. Nov 2004 15:53

Re: Speicherverbrauch eines Objektes
 
@Dax
nach Deiner Aussage
Delphi-Quellcode:
n1 := strListe.InstanceSize;
strListe.Add('Heute');
strListe.Add('ist');
strListe.Add('ein');
strListe.Add('schöner');
strListe.Add('Tag');
n2 := strListe.InstanceSize;
müsste n1 <> n2 sein, n1 = n2 = 48

@jbg
Zitat:

Für was brauchst du denn diese Information?
ich habe das Problem in einer selbstgeschriebenen Klasse, dass diese Speicher alloziert und nicht mehr freigeben kann

Zitat:

Der belegte Speicher ist querfeldein verstreut und kein zusammenhängender Block, was z.B. ein einfaches Schreiben in einen Stream unmöglich macht (dafür gibt es ja SaveToStream).
das muss für mich der Speichermanager von Borland/Delphi und das Betriebssystem übernehmen
darum kann ich mich nicht auch noch kümmern

Zitat:

Das dürfte hinkommen:
TStringList.InstanceSize + StrList.Capacity * SizeOf(TStringItem) + (Length(StrList[0]) + 12) + (Length(StrList[1]) + 12) + ... + (Length(StrList[Count-1]) + 12)
sicherlich könnte man das noch vereinfachen ...
es ist nicht nur eine TStringList - das war nur ein einfaches Beispiel
sondern die Klasse enthält zig andere Componenten und Listen
deswegen denke ich, dass es noch eine allgemeinere Antwort darauf geben könnte

Muetze1 4. Nov 2004 16:52

Re: Speicherverbrauch eines Objektes
 
Moin!

Zitat:

Zitat von trifid
@Dax
nach Deiner Aussage
Delphi-Quellcode:
n1 := strListe.InstanceSize;
strListe.Add('Heute');
strListe.Add('ist');
strListe.Add('ein');
strListe.Add('schöner');
strListe.Add('Tag');
n2 := strListe.InstanceSize;
müsste n1 <> n2 sein, n1 = n2 = 48

[/quote]

Er gibt auch nur den Platz zurück, den die Instanz braucht für ihre Membervariablen und nix weiter. Selbst die Strings bei dem Beispiel TStringList wird intern in der Klasse nur mit 4 Byte angerechnet, da es ein Pointer ist. Und somit müsstest du theoretisch die Vererbungskette von dem Objekt rückwärts durchlaufen und bei jeder Klasse das InstanceSize aufsummieren - was dann immernoch nicht Daten wie z.B. Strings mit beinhaltet.

Zitat:

Zitat von trifid
@jbg
Zitat:

Für was brauchst du denn diese Information?
ich habe das Problem in einer selbstgeschriebenen Klasse, dass diese Speicher alloziert und nicht mehr freigeben kann

Ich glaube dieser Ansatz hier hilft dir nicht bei der Lösung des Problems. In wie fern äussert sich denn der Fehler, das du kein Speicher mehr freigeben kannst? Wie kommst du darauf? Nur weil der Taskmanager nicht wieder einen kleineren Wert anzeigt nach einem .Free? Wenn es das letztere ist: sei unbesorgt: Der Delphi Heap Manager verkleinert nicht freiwillig seinen Bereich - wenn der einmal so gross ist, dann bleibt er es bis zum Ende ...

MfG
Muetze1

trifid 4. Nov 2004 19:57

Re: Speicherverbrauch eines Objektes
 
@Muetze1
Zitat:

In wie fern äussert sich denn der Fehler, das du kein Speicher mehr freigeben kannst?
Wie kommst du darauf? Nur weil der Taskmanager nicht wieder einen kleineren Wert anzeigt nach einem .Free? Wenn es das letztere ist: sei unbesorgt: Der Delphi Heap Manager verkleinert nicht freiwillig seinen Bereich - wenn der einmal so gross ist, dann bleibt er es bis zum Ende ...
nicht so schnell, nicht so schnell
Ich reserviere mit Absicht Speicher, damit ich dadurch gewisse Erleichterungen habe
Ich bekomme keinen Fehler - noch nicht
Nun möchte ich wissen, wenn ich das Teil/Objekt 10000 am Tag aufrufe (was vorraussichtlich nicht passiert), wieviel Speicher dabei verwendet wird.
Wenn ich weiss wieviel Speicher dabei benötigt wird, kann ich auch die Situation besser einschätzen.

Ich habe eine Möglichkeit gefunden für TComponent's
Delphi-Quellcode:
   
   mem := TMemoryStream.Create;
   try
      mem.WriteComponent (Form1);
      n := mem.Size;
   finally
      mem.Free;
   end;
Jedoch muss hier in der Vererbungshierarchie ein TComponent sein.
d.h. TForm ist von TComponent
TStringList aber nicht
Ich bin darauf gekommen, weil man auch von einer Persitenz eines Objektes reden kann/könnte - und diese kann man bestimmt durch eine Byte-Grösse beschreiben.
Aber vielleicht gibt es doch noch was allgemeineres was für Alle, die nach TObjekt kommen, funktionieren könnte.

Muetze1 4. Nov 2004 22:09

Re: Speicherverbrauch eines Objektes
 
Moin!

Dir ist bewusst, dass WriteComponent das gleiche rausschreibt was nachher in deiner DFM Datei steht und somit keine verlässliche Grössenangabe ist sondern rein die Werte der Properties des Objektes ?

Wenn du eine solche Einschätzung machen musst - dann bau ein Testprojekt was dein Objekt 100000 mal instanziiert und den Speicher alloziiert. Dann kannst du doch die Speicherdifferenz im Taskmanager "messen" und dann einen Richtwert ausrechnen pro Instanz...

Grundlegend kann ich dir versichern das deine ganzen Bemühungen so überhaupt nichts bringen - da wäre die Erfolgsaussichten höher, wenn du einen eigenen Heap Memory Manager schreibst und versuchst die ganzen Alloziierungen zu zu ordnen zu den Objekten....

MfG
Muetze1

trifid 5. Nov 2004 01:33

Re: Speicherverbrauch eines Objektes
 
Zitat:

Wenn du eine solche Einschätzung machen musst - dann bau ein Testprojekt was dein Objekt 100000 mal instanziiert und den Speicher alloziiert. Dann kannst du doch die Speicherdifferenz im Taskmanager "messen" und dann einen Richtwert ausrechnen pro Instanz...
das werde ich auch so machen, ich teste was an Heap verwendet wird.

Zitat:

Grundlegend kann ich dir versichern das deine ganzen Bemühungen so überhaupt nichts bringen - da wäre die Erfolgsaussichten höher, wenn du einen eigenen Heap Memory Manager schreibst und versuchst die ganzen Alloziierungen zu zu ordnen zu den Objekten....
soweit möchte ich nun doch wieder nicht gehen ... vielleicht gibt's da was bei Torry

Danke


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:21 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