Recursive Class Instance Size in Delphi

2020-03-25 03:43发布

问题:

Is there a way to get the actual size of a class instance in Delphi?

I know about the InstanceSize method of the TObject class but that method does not recursively invokes itself for object members. For example, let's say we have two classes:

type MyClass1 = class
  private
    myVar1 : integer;
    myVar2 : integer;
end;

type MyClass2 = class
  private
    myOtherVar1 : integer;
    myOtherVar2 : MyClass1;
end;

for this segment of code, MyClass1 will be 12 bytes length (4 bytes for each integer plus 4 for the class overhead) and MyClass2 will be 24 bytes lengh (4 bytes for the class overhead, 12 bytes from myOtherVar2 and another 4 for the myOtherVar1 integer). Using InstanceSize will result on 12 bytes for each of them since myOtherVar2 is interpreted as a pointer (4 bytes) instead of as a class reference.

Is there a way to get the total size of the class including its reference to other class instances?

回答1:

Construct one MyClass1 object and a million MyClass2 such that each MyClass2 points to the same MyClass1.

How much memory does each MyClass2 take? 12.000012 bytes?

How much memory does a circular list take? Infinity as you can keep chasing pointers for ever?

In languages with pointers, a naive recursive size-of algorithm isn't useful in general. You need to write your own algorithm which embodies knowledge about the aggregation/composition, sharing and recursive references specific to how you're using the objects.



回答2:

Is there a way to get the total size of the class including its reference to other class instances?

You just said it. The reference is a pointer; its size is 4 bytes. The value returned by InstanceSize is the number of bytes allocated for instance data of the class.

myOtherVar2 might be nil, for example. But the nil pointer value would still occupy 4 bytes of memory.



回答3:

to find out how much memory it uses, you could let the objects not get freed & let FastMM tell you the size of the leak.



回答4:

No what you want does not exist. If you want something like that, you should write it yourself.



回答5:

It sounds like you want to count memory used by your objects.

If you need to do that, you can check how FastMM does it, and may be hook your procedure when objects of your type get created.

A lot of work with unclear goal; You better have a good reason before starting it.