託管記憶體 (Managed Memory)

var student = new Student();

使用 new 關鍵字就會分配到一個堆積記憶體 (heap memory) 區塊,不需要手動釋放。由 GC 管理並決定何時釋放。因此稱為託管記憶體。

堆疊記憶體 (Stack Memory)

unsafe
{
    var stackMemory = stackalloc byte[100];
}

堆疊記憶體也不需要手動釋放,離開 scope 後就會自動被釋放。堆疊記憶體的容量非常小 (ARM、x86 和 x64 架構下,堆疊記憶體預設大小為 1 MB),如果超出使用容量就會擲出 StackOverflowException

非託管記憶體 (Unmanaged Memory)

nint nativeMemory0 = default;
nint nativeMemory1 = default;
try
{
    nativeMemory0 = Marshal.AllocHGlobal(256);
    nativeMemory1 = Marshal.AllocCoTaskMem(256);
}
finally
{
    Marshal.FreeHGlobal(nativeMemory0);
    Marshal.FreeCoTaskMem(nativeMemory1);
}

使用 Marshal 類別Marshal.AllocHGlobalMarshal.AllocCoTaskMem 來分配非託管記憶體。非托管就是不受 GC 管理的意思,因此需要手動呼叫 Marshal.FreeHGlobalMarshal.FreeCoTaskMem 來釋放,若沒有正確釋放會發生記憶體洩漏。

至於 AllocCoTaskMem 和 AllocHGlobal,應該都是選擇 AllocCoTaskMemAllocHGlobal 是為了特殊目的使用的。

References