你是对的:TObject.InstanceSize
返回内存中的实例大小。不是嵌套字段。
如果您想计算内存中类实例的“大小”,那么该值将永远不会与任何流式处理过程相匹配。
我的意思是,如果您将 class
实例序列化为 a TStream
,则大小将取决于实际的序列化。不是使用的总内存大小。大多数序列化引擎只会序列化已发布的属性,而不是公共的和嵌套的受保护字段。如果您序列化为 JSON、DFM 二进制、DFM 文本、ProtoBuf 或我们的 mORMot 二进制布局,您将有不同的值,这与实际的 RAM 消耗不匹配。
这种情况对于嵌套引用类型(例如string
或动态数组)来说甚至是值得的。他们使用引用计数,所以一个string
实例,如果在多个属性/变量中重用,只会在所有出现时消耗它的长度一次......那么嵌套对象呢,它可以在实例之间重用?
class
所以没有简单的方法来计算一个实例消耗了多少“内存” 。您可以做的是编写自己的函数,并对消耗的内存进行“估计”。就像是
function TMyObject.ConsumedBytes: integer;
begin
result := InstanceSize +
length(fName) * SizeOf(char) +
length(fFirstName) * SizeOf(char) +
length(fAddress) * SizeOf(char);
end;
即使这也将被视为一种估计,而不是消耗了多少 RAM。例如,某些类型string
确实在文本之前有一个标题(包括长度、引用计数和代码页),并且内存管理器本身总是会保留比实际需要的多一点,出于优化的低级原因。
我想你需要完善你的目标。如果要检查内存使用情况,那么您需要更多地了解 Delphi 如何将其内存用于其低级类型,以及堆内存管理器如何从操作系统中保留内存区域。