I believe that the size of the header is two words - one for the type reference and one for the synchronization block and other flags. The padding (I think) is enough to round the total size to an integer number of words.
For example, a reference type with only "int" takes 12 bytes on x86, as shown here:
using System;
public class Foo
{
int x;
public Foo(int x)
{
this.x = x;
}
}
public class Test
{
static void Main(string[] args)
{
int length = int.Parse(args[0]);
Foo x = new Foo(0);
Foo[] array = new Foo[length];
long start = GC.GetTotalMemory(true);
for (int i=0; i < length; i++)
{
array[i] = new Foo(i);
}
long end = GC.GetTotalMemory(true);
GC.KeepAlive(array);
GC.KeepAlive(x);
decimal totalDecimal = end-start;
Console.WriteLine(totalDecimal / length);
}
}
One interesting point - for some reason, an instance of System.Object takes 12 bytes (on x86) instead of 8, which I would otherwise have predicted. As if the minimum size is 12 bytes, but you get the first four bytes of real data :)
, , btw - , , , - . 12, 12, , -, . ( , arg, . .) , , - .