You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用GCHandle.Alloc()访问操作固定内存?长期固定内存使用疑问

Understanding Long-Term Memory Pinning with GCHandle.Pinned

Great question—let’s break this down clearly:

Yes, when you pin an array using GCHandle.Alloc(data, GCHandleType.Pinned), accessing the array via its indexer (data[i] = i) still operates directly on the pinned memory region.

Here’s why:
Pinning a managed object (like your byte array) tells the garbage collector not to relocate its underlying memory. The managed reference data still points to the exact same physical memory location it did before pinning. Normal managed operations on the array (indexers, foreach loops, etc.) work exactly as they always did—you just don’t have to worry about the GC moving the memory out from under you mid-operation.

When do you need AddrOfPinnedObject()?

You only need to call handle.AddrOfPinnedObject() when you need an unmanaged pointer to the memory (e.g., for interacting with native DLLs that expect a raw void* or IntPtr). For purely managed operations on the array, stick to the standard indexer—there’s no need to use the pointer directly.

Example Usage

Here’s a safe, complete example to illustrate:

byte[] data = new byte[10];
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);

try
{
    // This modifies the pinned memory directly via the managed array reference
    for (int i = 0; i < data.Length; i++)
    {
        data[i] = (byte)i;
    }

    // Use AddrOfPinnedObject() only when you need an unmanaged pointer (for interop)
    IntPtr rawPointer = handle.AddrOfPinnedObject();
    // Example: Pass rawPointer to a native function here
}
finally
{
    // Critical: Always free the handle to release the pin and avoid memory leaks
    handle.Free();
}

Key Notes

  • Never skip freeing the handle: Forgetting handle.Free() leaves the memory pinned indefinitely, causing heap fragmentation and performance issues. Use a try/finally block to ensure cleanup even if an exception occurs.
  • fixed vs GCHandle.Pinned: The fixed keyword is for short-lived pinning (within a single code block, as it auto-releases when the block exits). Use GCHandle.Pinned when you need to keep memory pinned across method calls or for longer durations.
  • Minimize pinning time: Pinned memory limits the GC’s ability to compact the heap, so only pin when necessary and release the handle as soon as possible.

内容的提问来源于stack exchange,提问作者meci

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 11:22:30