C# Memory-Alignment

EDIT:
You can ignore most of the stuff written here. Rule of thumb. Classes will out of the box arrange the data-structures as good as possible, structs build their data-structure (JIT-wise) as the code tells if not [StructLayout(LayoutKind.Auto)] is set. The rest of the text might still be interesting for people who do want to have 100% control over their datastructure (guess that are not too many 😉).


If writing code in C# you need(?) be aware that the order of variables inside of structs and classes result in different memory-consumptions on the JIT-ASM side of life. I tested this with sharplab.io.
Structs:

There are two arrays a=Test[] and aligned2=TestAligned[].
Test-class is using int(4bytes wide) and byte(1 byte wide) alternating. Due to memory padding/alignment after the byte-elements the compiler will add empty 3bytes (the padding) which basically is lost memory.
By reordering the datatype like in TestAligned you are packing the data so that no padding is needed.
In this example i allocate an array of Test(Aligned)-Structs and compare the memory addresses of the last element to see the difference.
Using struct arrays results in one memory-block housing all the struct-data one after an other ('physically'). Accessing the last elements of the the array will show us the difference size-consumption.

1) the 9-value being written to the last element in Test[]-array to address 0xc84(3204 decimal)
2) the 6-value being written to the laste lement in TestAligned[]-array to address 0x7d7 (2007 decimal)
This makes a difference of 1197bytes just by reordering the data-structure which can add up quite a lot.

Same is true for storing the data within classes instead of structs:

Classes:

Arrays of classes are basically arrays of pointers to the data, so here the assembly first need to point to the address of the object(in this case there are 100different) and after wards set the data in this address-space:

1) write 9-value to position 0x20(32 decimal)
2) write 6-value to position 0x17(23 decimal)
You see there is a 32-23=9bytes difference per object (to access this address). Is this case you should actually add another 3bytes due to alignment after the last byte in Test-Class.

I guess it is something everybody no matter if using c-structs or c#-structs/classes should be aware of.