sizeof() 等效于引用类型?
Posted
技术标签:
【中文标题】sizeof() 等效于引用类型?【英文标题】:sizeof() equivalent for reference types? 【发布时间】:2010-09-06 19:05:15 【问题描述】:我正在寻找一种方法来获取引用类型实例的大小。 sizeof 仅适用于值类型。这可能吗?
【问题讨论】:
这不是问题,只是好奇心的练习。在整个请求中,我有一堆项目进入 HttpContext.Items,我只是好奇它们占用了多少内存(如果它甚至很重要)。我正在经历“衡量一切”阶段。 还有其他方法可以确定这一点(无需修改代码)。只需使用内存分析器。任何体面的分析器都会向您显示每个特定实例分配的字节数以及该实例持有的所有内存,包括引用实例占用的内存。 【参考方案1】:你需要Marshal.SizeOf
编辑:这是用于不安全的代码,但是 sizeof() 也是如此。
【讨论】:
Marshal.SizeOf 返回的字节数可能与使用的字节数不同。【参考方案2】:如果您不介意它的准确度不如完美,并且出于比较目的,您可以序列化对象并测量它(例如以字节为单位)
编辑(发帖后我一直在想):因为对于值类型来说,它比 sizeof 稍微复杂一点,例如:引用类型可以引用其他对象等等……没有我知道的准确而简单的方法......
【讨论】:
【参考方案3】:我最近有一个类似的问题,想知道 C# 中 Object 和 LinkedListNode 的大小。为了解决这个问题,我开发了一个program,它将:
-
测量程序的“工作集”
分配大量对象。
再次测量“工作集”。
将差值除以分配的对象数。
在我的电脑(64 位)上,我得到了以下数据:
Measuring Object:
iter working set size estimate
-1 11190272
1000000 85995520 74.805248
2000000 159186944 73.998336
3000000 231473152 73.4276266666667
4000000 306401280 73.802752
5000000 379092992 73.580544
6000000 451387392 73.3661866666667
7000000 524378112 73.3125485714286
8000000 600096768 73.613312
9000000 676405248 73.9127751111111
Average size: 73.7577032239859
Measuring LinkedListNode<Object>:
iter working set size estimate
-1 34168832
1000000 147959808 113.790976
2000000 268963840 117.397504
3000000 387796992 117.876053333333
4000000 507973632 118.4512
5000000 628379648 118.8421632
6000000 748834816 119.110997333333
7000000 869265408 119.299510857143
8000000 993509376 119.917568
9000000 1114038272 119.985493333333
Average size: 118.296829561905
Estimated Object size: 29.218576886067
Estimated LinkedListNode<reference type> size: 44.5391263379189
根据数据,分配数百万个 Object 的平均大小约为 29.2 字节。一个 LinkedListNode 对象大约是 44.5 字节。该数据说明了两件事:
-
系统分配部分字节的可能性很小。字节的小数部分表示 CLR 分配和跟踪数百万个引用类型所需的开销。
如果我们只是对字节数进行四舍五入,我们仍然不太可能为引用类型获得正确的字节数。这从物体的测量中可以清楚地看出。如果我们向下取整,我们假设大小为 29 字节,虽然理论上可能,但由于填充而不太可能。为了提高性能,通常会填充对象分配以用于对齐目的。我猜 CLR 对象将是 4 字节对齐的。
假设 CLR 开销和 4 字节对齐,我估计 C# 中的 Object 是 28 字节,LinkedListNode 是 44 字节。
顺便说一句,Jon Skeet 在我之前就有了上述方法的想法,并在this answer 中针对类似的问题进行了说明。
【讨论】:
【参考方案4】:注意 Marshal.SizeOf 用于不安全的代码...
我认为托管代码不可能,也许你可以解释你的问题,可能有另一种方法来解决它
【讨论】:
【参考方案5】:如果可以的话 - 序列化它!
Dim myObjectSize As Long
Dim ms As New IO.MemoryStream
Dim bf As New Runtime.Serialization.Formatters.Binary.BinaryFormatter()
bf.Serialize(ms, myObject)
myObjectSize = ms.Position
【讨论】:
【参考方案6】:请参考我在以下链接中的回答。
可以通过 .sos.dll 调试器扩展来实现
Find out the size of a .net object
【讨论】:
以上是关于sizeof() 等效于引用类型?的主要内容,如果未能解决你的问题,请参考以下文章