- How big is instance of following class after constructor is called?
I guess this can be written generally as size = nx + c, where x = 4
in x86, and x = 8 in x64. n = ? c = ?
- Is there some method in .NET which can return this number?
class Node
{
byte[][] a;
int[] b;
List<Node> c;
public Node()
{
a = new byte[3][];
b = new int[3];
c = new List<Node>(0);
}
}
First of all this depends on environment where this program is compiled and run, but if you fix some variables you can get pretty good guess.
Answer to 2) is NO, there is no function that will give you requested answer for any object given as argument.
In solving 1) you have two approaches:
- Try to perform some tests to find out
- Analyze the object and do the math
Test approach
First take a look at these:
- what-is-the-memory-overhead-of-a-net-object
- Overhead of a .NET array?
- C# List size vs double[] size
Method you need is this:
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);
}
On my Windows 7 machine, VS 2012, .NET 4.5, x86 (32 bit) result is 96.000. When changed to x64 result is 176.000.
Do the math approach
Do the math approach can be written as a function that will give you result, but is specific for your Node class, and it is only valid before other operations on your object are performed. Also notice that this is made in 32-bit program and also note that this number can change with framework implementation and version. This is just example how you can give pretty good guess about object size in some moment if object is simple enough. Array and List overhead constants are taken from Overhead of a .NET array? and 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;
}
This will also return 96 so I assume that method is correct.