Memory layout of objects (instances of a class)
At offset 0 resides the virtual method table. Starting from ofsset 4 comes the fields. Just like in Delphi.
Number of associated methods
The number of associated methods and if they are virtual does not influence the object size. Just like in Delphi.
Type of the fields
According to the cited article, Delphi reserves 4 bytes for each field even if the type has a size of 1 byte. Here comes the fun.
Take the following classes:
TOneFlagClass = class
Flag1: Boolean;
end;
TTwoFlagClass = class
Flag1: Boolean;
Flag2: Boolean;
end;
The size of TOneFlagClass and TTwoFlagClass are 5 and 6 bytes respectively (4 for the vmt and 1 for each field). The memory offsets of Flag1 and Flag2 are 4 and 5.
Delphi is a bit different here. The size of both classes are 8. The memory offsets of the fields are the same as fpc.
At this time i think: "In this case is better to place less than 4 bytes fields at the end of the class declaration to avoid subsequent fields to be accessed outside the dword boundary"
I was wrong. In fact half wrong:
Take the following classes:
TFlagFirstClass = classThe size of TFlagFirstClass and TFlagLastClass are 12 and 9 respectively. The compiler allocates 4 bytes for the boolean field to maintain subsequent fields (that has a size of 4 bytes) aligned with the dword boundary.
Flag1: Boolean;
Int1: Integer;
end;
TFlagLastClass = class
Int1: Integer;
Flag1: Boolean;
end;
If another boolean field (Flag2) is added just after Flag1, the instance size is not affected. In fact, grouping 4 boolean (or another 1 byte type) fields together will lead to the same instance size as only one boolean field if those are succeeded by Integer or Pointer like types.
In the end, my suggestion is still valid: put the "less than 4 bytes field types" at the end of the field declaration of the class (or group together in groups with 4 bytes in total). You will save some memory.
If you are not convinced compare size of a class with the following fields sequence:
Boolean, Integer, Boolean, Integer, Boolean, Integer, Boolean, Integer
Boolean, Boolean, Boolean, Boolean, Integer, Integer, Integer, Integer
Integer, Integer, Integer, Integer, Boolean, Boolean, Boolean, Boolean
Some notes:
- Object here is not referenced as the object type (that has the same memory layout of a record), but as the instance of a class
- There's no difference between mode delphi and objfpc
- It's valid only for i386 architeture. No idea how this works in ppc, amd64, arm
3 comments:
Hi Luiz Americo,you ask permission to publish the tutorials that you have written to the Spanish first what you see in http://cacharreandoando.blogspot.com/
No problem, keep doing.
This is much like so called "C alignment", iow fields with size "X" are allocated on size "x" borders.
It shouldn't matter btw if booleans are first or last, as long as they are grouped.
Post a Comment