Method Table, TypeHandle & Object Header Memory Layout
1Concept
Every reference type instance on the managed heap carries an 8-byte SyncBlockIndex and an 8-byte MethodTable pointer (TypeHandle) on 64-bit architectures, establishing an object header overhead of 16 bytes before any user fields.
2Architecture Diagram
64-Bit Heap Object Layout (Minimum 24 Bytes): ┌───────────────────────────┬───────────────────────────┬───────────────────────────┐ │ SyncBlockIndex (8 Bytes) │ MethodTable Ptr (8 Bytes)│ User Field Data (8+ Bytes)│ └───────────────────────────┴───────────────────────────┴───────────────────────────┘ ▲ Lock state, hashcode ▲ Virtual method vtable ▲ Instance fields & padding
3Code Example
C# 13 & .NET 9
using System;
using System.Runtime.InteropServices;
public class HeaderDemo
{
public class SamplePayload
{
public int Id; // 4 bytes
public int Age; // 4 bytes
}
public static void Main()
{
var obj = new SamplePayload { Id = 101, Age = 28 };
Console.WriteLine($"Type Name: {obj.GetType().FullName}");
Console.WriteLine($"TypeHandle: {obj.GetType().TypeHandle.Value:X}");
Console.WriteLine("Object has 16-byte header (SyncBlock + MethodTable) + 8-byte fields.");
}
}4Expected Output
Type Name: HeaderDemo+SamplePayload TypeHandle: 7FF8A4B29010 Object has 16-byte header (SyncBlock + MethodTable) + 8-byte fields.
5Key Takeaways
- ✓Small reference types incur a 16-byte overhead on 64-bit systems.
- ✓SyncBlock holds monitor lock data and lazily computed hash codes.
- ✓Value types (`struct`) have NO object header when placed on stack or embedded in arrays.