![]() |
Speicherplatz ermitteln: Objekt vs. Record
Hallo,
wollte allgemein mal nachfragen, wie ich den genauen Speicherplatz von einer Instanz einer Klasse (samt darin gekapselten Objekten) und einem Record (samt darin gekapselten Objekten) ermitteln kann? Und zwar komme ich auf diese Frage, da RTTI in D2010 leider ein Problem mit meinem Record hat und ich in der Zwischenzeit kurz davor bin auf ein Klasse umzusteigen. Ich finde das im Prinzip zwar erst mal totaler Overhead, aber da habe ich dann doch lieber einen gut lesbaren Code, aber etwas weniger Performance. So viel verkraftet der Benutzer dann doch noch :zwinker: Wenn ihr mir im Speziellen noch helfen wollte:
Delphi-Quellcode:
// ----- Record -----
RInteger = record private FValue : Variant; // Kann durch Setter nur NULL werden oder eine Zahl beinhalten procedure SetValue(const AVar: Variant); public const VarType = varInteger; property Value : Variant read FValue write SetValue; function IsNull(): Boolean; end; // ----- In eine Klasse gefasst ----- RInteger = class(TObject) private FValue : Variant; // Kann durch Setter nur NULL werden oder eine Zahl beinhalten procedure SetValue(const AVar: Variant); public const VarType = varInteger; property Value : Variant read FValue write SetValue; function IsNull(): Boolean; end; |
Re: Speicherplatz ermitteln: Objekt vs. Record
Hallo,
schnapp dir MemCheck oder FastMM4, erzeuge die Klasse und den Record (New PRecord), ohne sie wieder freizugeben. Und schon zeigen dir beide Programme den exakten Speicherverbrauch an (mem leak). Heiko |
Re: Speicherplatz ermitteln: Objekt vs. Record
Also mindestens sein Turbo Delphi ist das nicht nötig.
Es gibt eine globale Variable ReportMemoryLeaksOnShutdown (könnte vllt. etwas anders heißen konnte ich grad nicht nachprüfen) Setz die einfach beim Programmstart auf true und mach sonst soweit das gleiche was Hoika meinte. (Instanz erzeugen und nicht freigeben) Pass aber auf das nicht vorher schon irgendwelche mem-leaks da sind (also vorher mal mit ReportMemoryLeaksOnShutdown = true ausführen, ohne die Instanz zu erzeugen) Bei einer Klasse müsste auch InstanzeSize gehen (das klappt aber ja nicht, wenn du auch den Speicherverbrauch von Objekten, Strings usw. in der Klasse ermitteln willst) Aber InstanzeSize (Klasse) und SizeOf (Record) kannst du für einen Vergleich nutzen, wenn beide den gleichen Inhalt haben. MFG |
Re: Speicherplatz ermitteln: Objekt vs. Record
Moin,
was hältst du von einem PInteger?
Delphi-Quellcode:
MfG
RInteger = record
private FValue : PInteger; public property Value : PInteger read FValue write FValue; function IsNull(): Boolean; end; Fabian |
Re: Speicherplatz ermitteln: Objekt vs. Record
Delphi-Quellcode:
Kleiner ist dagegen dann nur noch die Verwendung eines Wertes aus dem Wertebereich des Integers, welchen man dann als NULL ansieht.
RInteger = {packed} record
private FValue : Integer; FNull : Boolean; public procedure SetNull(yes : Boolean = true); property Value : PInteger read GetValue write SetValue; property IsNull : Boolean read FNull write SetNull; end; Wenn man ein Objekt nur als Datenspeicher nutzt, dann ist der Record immer einen Hauch kleiner, da die Verwaltung des Objektes wegfällt.
Delphi-Quellcode:
= 8 12
type
TRec = record a, b: Integer; end; TCls = class a, b: Integer; end; ShowMessage(Format('%d %d', [SizeOf(TRec), TCls.InstanceSize])); Die 4 zusätzlichen Byte sind die Referenz auf den Klassentypen, dazu kommt dann noch ein bissl mehr an RTTI-Daten (ich denk mal, daß wird sich auch in der neuen RTTI nicht geändert haben). |
Re: Speicherplatz ermitteln: Objekt vs. Record
Zitat:
Das würde aber zu einigen Problemen führen: - dass eine Objektinstanz von mehreren anderen Stellen aus referenziert wird. Wie ermittelst du dann den Speicherverbrauch deiner referenzierenden Objekte? - dass Objektinstanzen sich gegenseitig referenzieren. Welche Instanz verbraucht dann Speicherplatz von welcher anderen? Alles in allem keine einfache Angelegenheit. |
Re: Speicherplatz ermitteln: Objekt vs. Record
Okay, Prinzip verstanden :thumb: Ich müsste dann halt evtl. auch noch jedes Variable rekursiv durchgehen, wenn es sich denn um ein Objekt handelt.
Wobei es scheinbar doch nicht soo viel mehr an Overhead ist, wie ich anfangs befürchtet hatte :zwinker: Es enstehen halt geschätzt ~10000 Objekte anstatt Records (was zuvor einfach Variablen waren, aber durch das ![]() Hier das was ich via der FastMM-Methoder herausgefunden habe:
Code:
Record:
20 Bytes -> bei 10000 Objekten -> 200000 Bytes ->195 KB Objekt: 28 Bytes -> bei 10000 Objekten -> 280000 Bytes -> 273 KB => 40% mehr |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:13 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz