我的类使用了多少内存实例 - 务实的答案

wat*_*rif 5 .net c# memory-management micro-optimization

  1. 调用构造函数后,以下类的实例有多大?我想这通常可以写为 size = nx + c,其中 x86 中 x = 4,x64 中 x = 8。n = ? c = ?
  2. .NET 中是否有某种方法可以返回这个数字?

class Node { byte[][] a; int[] b; List<Node> c; public Node() { a = new byte[3][]; b = new int[3]; c = new List<Node>(0); } }

wat*_*rif 5

首先,这取决于该程序编译和运行的环境,但是如果您修复一些变量,您可以获得很好的猜测。

2) 的答案是否定的,没有任何函数可以为作为参数给出的任何对象提供所需的答案。

在解决 1) 时,您有两种方法:

  • 尝试进行一些测试来找出答案
  • 分析物体并进行数学计算

测试方法

首先看看这些:

你需要的方法是这样的:

const int Size = 100000;
private static void InstanceOverheadTest()
{
    object[] array = new object[Size];
    long initialMemory = GC.GetTotalMemory(true);
    for (int i = 0; i < Size; i++)
    {
        array[i] = new Node();
    }
    long finalMemory = GC.GetTotalMemory(true);
    GC.KeepAlive(array);
    long total = finalMemory - initialMemory;
    Console.WriteLine("Measured size of each element: {0:0.000} bytes",
                      ((double)total) / Size);
}
Run Code Online (Sandbox Code Playgroud)

在我的 Windows 7 计算机上,VS 2012、.NET 4.5、x86(32 位)结果为 96.000。更改为 x64 时结果为 176.000。

做数学方法

Do 数学方法可以写成一个函数来给出结果,但它是特定于 Node 类的,并且它仅在对对象执行其他操作之前有效。另请注意,这是在 32 位程序中创建的,并且还要注意该数字可能会随着框架实现和版本的变化而变化。这只是一个示例,如果对象足够简单,您可以在某个时刻很好地猜测对象的大小。数组和列表开销常量是否取自.NET 数组的开销?C# 列表大小与 double[] 大小

public const int PointerSize32 = 4;
public const int ValueArrayOverhead32 = 12;
public const int RefArrayOverhead32 = 16;
public const int ListOverhead32 = 32;
private static int instanceOverheadAssume32()
{
    int sa = RefArrayOverhead32 + 3 * PointerSize32;
    int sb = ValueArrayOverhead32 + 3 * sizeof(int);
    int sc = ListOverhead32;
    return 3 * PointerSize32 + sa + sb + sc;
}
Run Code Online (Sandbox Code Playgroud)

这也将返回 96 所以我认为该方法是正确的。