Memory layout of a .NET array

One way to examine this is to look at the code in WinDbg. So given the code below, let’s see how that appears on the heap.

var numbers = new Int32[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

The first thing to do is to locate the instance. As I have made this a local in Main(), it is easy to find the address of the instance.

From the address we can dump the actual instance, which gives us:

0:000> !do 0x0141ffc0
Name: System.Int32[]
MethodTable: 01309584
EEClass: 01309510
Size: 52(0x34) bytes
Array: Rank 1, Number of elements 10, Type Int32
Element Type: System.Int32
Fields:
None

This tells us that it is our Int32 array with 10 elements and a total size of 52 bytes.

Let’s dump the memory where the instance is located.

0:000> d 0x0141ffc0
0141ffc0 [84 95 30 01 0a 00 00 00-00 00 00 00 01 00 00 00  ..0.............
0141ffd0  02 00 00 00 03 00 00 00-04 00 00 00 05 00 00 00  ................
0141ffe0  06 00 00 00 07 00 00 00-08 00 00 00 09 00 00 00  ................
0141fff0  00 00 00 00]a0 20 40 03-00 00 00 00 00 00 00 00  ..... @.........
01420000  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
01420010  10 6d 99 00 00 00 00 00-00 00 01 40 50 f7 3d 03  .m.........@P.=.
01420020  03 00 00 00 08 00 00 00-00 01 00 00 00 00 00 00  ................
01420030  1c 24 40 03 00 00 00 00-00 00 00 00 00 00 00 00  .$@.............

I have inserted brackets for the 52 bytes.

  • The first four bytes are the reference to the method table at 01309584.
  • Then four bytes for the Length of the array.
  • Following that are the numbers 0 to 9 (each four bytes).
  • The last four bytes are null. I’m not entirely sure, but I guess that must be where the reference to the syncblock array is stored if the instance is used for locking.

Edit: Forgot length in first posting.

The listing is slightly incorrect because as romkyns points out the instance actually begins at the address – 4 and the first field is the Syncblock.

Leave a Comment