如何使用TMemoryStream.size计算delphi类的大小?

我正在尝试为示例 TControl、TWinControl 等查找内置类的大小。尝试使用 InstanceSize(),这反过来可能不会添加将它们视为引用的少数类型的大小。

发现一个有趣的堆栈溢出线程谈论 TMemoryStream 以找出类大小:以与文件大小相同的格式获取类或对象的大小?无法获得有关如何使用 TMemoryStream 确定班级大小的太多信息,我可以就此获得帮助吗?

回答

你是对的: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 如何将其内存用于其低级类型,以及堆内存管理器如何从操作系统保留内存区域。


以上是如何使用TMemoryStream.size计算delphi类的大小?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>