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

时间:2014-04-10 11:13:37

标签: c# .net memory-management micro-optimization

  1. 调用构造函数后跟随类的实例有多大? 我想这通常可以写成size = nx + c,其中x = 4 在x86中,x = 8中的x = 8。 n =? c =?
  2. .NET中是否有一些可以返回此数字的方法?
  3. class Node { byte[][] a; int[] b; List<Node> c; public Node() { a = new byte[3][]; b = new int[3]; c = new List<Node>(0); } }

1 个答案:

答案 0 :(得分:4)

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

对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);
}

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

做数学方法

数学方法是否可以作为一个函数编写,它将为您提供结果,但是特定于您的Node类,并且只有在对象的其他操作执行之前它才有效。另请注意,这是在32位程序中进行的,并且还注意到此数字可能随框架实现和版本而变化。这只是一个例子,如果对象足够简单,你可以在某个时刻对对象大小进行很好的猜测。数组和列表开销常量取自Overhead of a .NET array?C# List size vs double[] size

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;
}

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