Skip to content

Pinned objects

Context: The GC normally moves objects in memory during compaction. However, when interoperating with unmanaged code (e.g., using P/Invoke or System.Span<T>), you may need to fix an object’s address so that the GC does not move it. This is called pinning. Pinned objects are marked and the GC will skip moving them, which can cause heap fragmentation. You should pin objects only for the shortest possible time.

using System;
using System.Runtime.InteropServices;
public class PinningDemo
{
public static void PinArray()
{
byte[] buffer = new byte[1024];
GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
try
{
IntPtr address = handle.AddrOfPinnedObject();
Console.WriteLine($"Pinned address: {address}");
// Call unmanaged method here
}
finally
{
handle.Free();
}
}
}
Terminal window
dotnet run
Pinned address: 0x1B2F3A4C
  • Pinning prevents GC compaction, leading to fragmentation.
  • Use fixed statement in unsafe context for short pinning.
  • Avoid pinning large objects on LOH.

Calling native library – When you pass a byte array to a Windows API function like ReadFile, you may need to pin the array to ensure the GC doesn’t move it during the call.
See .NET docs on pinning.