Compaction moves live objects together on the .NET heap to create a larger contiguous region of free memory. It matters when an allocation needs one unbroken chunk, not merely enough free space in total. section 10.3.4
Imagine a 1 MB heap filled with successive allocations. Garbage collection frees unused chunks, but the gaps between live chunks may still be too small for a new array. Compacting the live chunks brings the free space together. section 10.3.4
The heap after compaction shows why moving live chunks can make a previously impossible allocation fit. section 10.3.4
Moving arrays matters when code uses pointers to their memory. In an `unsafe` copy routine, `fixed` keeps the source and target arrays at the same physical locations until the block finishes, so compaction cannot move them during the pointer-based copy. section 10.3.4
Listing 10.10 C# copy array using pointers instead of references
int[] CopyArray(int[] source)
{
int length = source.Length;
int[] target = new int[length]; #1
unsafe #2
{
fixed (int* pSource = source, #3
int* pTarget = target)
{
for (int i = 0; i < length; i++)
{
pTarget[i] = pSource[i]; #4
}
}
}
return target; #5
}
The pointer-based array copy places both arrays inside a `fixed` block before accessing their elements. section 10.3.4




