【问题标题】:sizeof() equivalent for reference types?sizeof() 等效于引用类型?
【发布时间】:2010-09-06 19:05:15
【问题描述】:

我正在寻找一种方法来获取引用类型实例的大小。 sizeof 仅适用于值类型。这可能吗?

【问题讨论】:

  • 这不是问题,只是好奇心的练习。在整个请求中,我有一堆项目进入 HttpContext.Items,我只是好奇它们占用了多少内存(如果它甚至很重要)。我正在经历“衡量一切”阶段。
  • 还有其他方法可以确定这一点(无需修改代码)。只需使用内存分析器。任何体面的分析器都会向您显示每个特定实例分配的字节数以及该实例持有的所有内存,包括引用实例占用的内存。

标签: c# .net


【解决方案1】:

你需要Marshal.SizeOf

编辑:用于不安全的代码,但是 sizeof() 也是如此。

【讨论】:

  • Marshal.SizeOf 返回的字节数可能与使用的字节数不同。
【解决方案2】:

如果您不介意它的准确度不如完美,并且出于比较目的,您可以序列化对象并测量它(例如以字节为单位)

编辑(发帖后我一直在想):因为对于值类型来说,它比 sizeof 稍微复杂一点,例如:引用类型可以引用其他对象等等……没有我知道的准确而简单的方法......

【讨论】:

    【解决方案3】:

    我最近有一个类似的问题,想知道 C# 中 Object 和 LinkedListNode 的大小。为了解决这个问题,我开发了一个program,它将:

    1. 测量程序的“工作集”
    2. 分配大量对象。
    3. 再次测量“工作集”。
    4. 将差值除以分配的对象数。

    在我的电脑(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 字节。该数据说明了两件事:

    1. 系统分配部分字节的可能性很小。字节的小数部分表示 CLR 分配和跟踪数百万个引用类型所需的开销。
    2. 如果我们只是对字节数进行四舍五入,我们仍然不太可能为引用类型获得正确的字节数。这从物体的测量中可以清楚地看出。如果我们向下取整,我们假设大小为 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

          【讨论】:

            猜你喜欢
            • 2023-03-05
            • 1970-01-01
            • 2012-09-01
            • 2012-02-13
            • 2017-10-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多