我试图优化我的Delphi类的大小,以便它们占用尽可能少的内存,因为我正在创建大量内存。
问题是,这些类本身是相当小的,但它们并没有占用我所期望的空间。例如,如果我有
type MyClass = class
private
mMember1 : integer;
mMember2 : boolean;
mMember3 : byte;
end;我希望它使用6个字节,但是,由于对齐,它最终使用了12个字节,也就是说布尔人消耗了4个字节,而不是1个字节.字节字段也是如此。
对于记录,可以使用{$A1}指令,也可以将其声明为打包记录,以使其只消耗所需的内存。
有什么办法在课堂上做同样的事情吗?(也许是关于如何正确覆盖NewInstance类方法的教程?)
编辑:好吧,关于我在做什么的一点解释.
首先,实际类大小大约是40个字节,包括VMT和接口指针占用的空间。
这些类都是从一个大小为8个字节的基类(一个整数RefCounting和一些允许引用计数的方法)继承的,它们必须支持接口(因此根本不使用打包记录)。
当处理程序不知道它们得到了什么时,这个对象就会被传递到多个对象中。例如,我有一个类,它接收TItems列表并执行如下操作:
if Supports(List[i], IValuable, IValInstance) then
Eval(IValInstance.Value);然后另一个处理程序可能会检查其他接口。
If Supports(List[i], IStringObject, IStringInstance) then
Compose(IStringInstance.Value)这样列表就会被每个Handler不同的对待..。
关于如何获得类的总大小,我使用了一个修改后的内存管理器,这样我就可以跟踪“真正”内存管理器为类消耗了多少内存。这样的话,我很有信心实例没有被打包。
最后,这是在Delphi 7中。我尝试使用{$A1}预编译器指令,没有运气,字段可以以任何方式对齐,而且我可能有几百万个实例作为最坏的情况,这样节省6个字节就可以节省几MB。
发布于 2009-05-07 00:54:11
您可以使用打包记录作为对象的字段:
type
TMyRecord = packed record
Member1 : integer;
Member2 : boolean;
Member3 : byte;
end;
TMyClass = class
private
FData : TMyRecord;
function GetMember1 : Integer;
public
property Member1 : Integer read GetMember1;
// Later versions of Delphi allow "read FData.Member1;", not sure when from
end;
function TMyClass.GetMember1 : integer;
begin
result := FData.Member1;
end;发布于 2009-05-06 20:54:35
如果您非常担心一些字节(您提到了6vs12),那么您就根本不应该使用一个类。用一张唱片代替。然后,您可以使用packed来消除对齐的浪费;但是,请准备好受到性能的影响,因为默认的“非打包”对齐是为CPU最快的访问设置的。
发布于 2009-05-06 19:01:31
为什么不一开始就使用打包记录呢?它将省去从TObject下降所引起的开销(轻微)。
https://stackoverflow.com/questions/831099
复制相似问题