This paper extracts a question from StackOverflow Overhead-of-a-net-array
Here are the key points:
Consider the following code
var New string [1]; var New int [1];strings[0"helloWorld"; ints[0 ;
Attaching WINDBG shows the following:
First let's take a look at the value type array.
0: the>!dumparray-details 017E2ACC name:system.int32[]methodtable:63b9aa40eeclass:6395b4d4size: -(0x10) Bytesarray:rank1, Number of elements1, Type int32element methodtable:63b9aaf0[0] 017e2ad4 Name:System.Int32 methodtable 63b9aaf0 eeclass:6395b548 Size: A(0xc) bytes (C:\Windows\assembly\GAC_32\mscorlib\2.0.0. 0__b77a5c561934e089\mscorlib.dll) FIELDS:MT Field Offset Type VT Attr Value Name 63b9aaf0 40003f00System.Int321Instance theM_value <===Our value0: the>!objsize 017E2ACCsizeof(017E2ACC) = -(0x10) bytes (system.int32[])0: the> DD 017E2ACC-0x4017e2ac80000000063b9aa40000000010000002A <=== that's The value
First we dump the array and the one element with value of 42. As can seen the size is bytes. That's 4 bytes int32 for the value itself, 8 bytes for regular reference type overhead and another 4 bytes for the length of the array.
The raw dump shows the SyncBlock, the method table for int[] , the length, and the value of a (2a in hex). Notice The SyncBlock is located just in front of the object reference.
Next, let's look at the-find out-what's the string[] additional word is used for.
0: the>!dumparray-details 017e2ab8 name:system.string[]methodtable:63b74ed0eeclass:6395a8a0size: -(0x14) Bytesarray:rank1, Number of elements1, Type classelement methodtable:63b988a4[0] 017e2a90 Name:System.String methodtable:63b988a4 eeclass:6395a498 Size: +(0x28) bytes <=== Size of thestring(C:\Windows\assembly\GAC_32\mscorlib\2.0.0. 0__b77a5c561934e089\mscorlib.dll) String:hello World fields:mt Field Offset Type VT Attr Value Name 63b 9aaf04000096 4System.Int321Instance Am_arraylength 63b9aaf04000097 8System.Int321Instance Onem_stringlength 63b995844000098C System.Char1Instance theM_firstchar 63b988a44000099 TenSystem.String0SharedStaticEmpty>> Domain:value00226438: 017e1198 <<63b994d4 400009a -System.char[]0SharedStaticWhitespacechars>> Domain:value00226438: 017e1760 <<0: the>!objsize 017e2ab8sizeof(017E2AB8) = -(0x3c) bytes (system.object[]) <=== Notice The underlying type of thestring[]0: the> DD 017e2ab8-0x4017E2AB40000000063b74ed00000000163B988A4 <=== Method Table for string017E2AC4 017e2a90<=== Address of thestring inchMemory0: the>!DUMPMT 63b988a4eeclass:6395a498module:63931000Name:System.StringmdToken:02000024(C:\Windows\assembly\GAC_32\mscorlib\2.0.0. 0__b77a5c561934e089\mscorlib.dll) Basesize:0x10componentsize:0x2Number of ifacesinchIfacemap:7SlotsinchVTable:196
First we dump the array and the string. Next We dump the size of the string[] . Notice that WINDBG lists, the type as here System.Object[] . The object size in this case includes the string itself, so the total size is the the "the" from the array plus the Ring.
By dumping the raw bytes of the instance we can see the following:first we had the SyncBlock, then follows the method Ta Ble object[] for, then the length of the array. After then we find the additional 4 bytes with the reference to the method table for string. This can is verified by the DUMPMT command as shown above. Finally we find the single reference to the actual string instance.
In conclusion
The overhead for arrays can being broken down as follows
- 4 bytes SyncBlock
- 4 bytes for Method table (type reference) for the array itself
- 4 bytes for Length of array
- Arrays of reference types adds another 4 bytes to hold the method table of the actual element type (reference type Arrays Is
object[] under the hood)
i.e. the overhead is a bytes for value type arrays and a bytes for reference type arrays.
Overhead of a. NET array