使用 GCHandle.Alloc() 访问和操作固定内存的正确方法是什么?

What is the correct way to access and manipulate pinned memory using GCHandle.Alloc()?

我正在尝试更好地了解如何将内存固定更长时间。很明显 GCHandle.Alloc(..., GCHandleType.Pinned) 是我需要使用的(超过 fixed(){})。

但是,我希望我能得到一些关于它的使用的说明。

如果我分配一个数组然后使用GCHandle固定它:

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

如果我像这样操作 data 数组:

for(int i = 0; i < data.length; i++) {
    data[i] = i;
}

我还在固定的内存区域上操作吗?或者我只能通过 handle.AddrOfPinnedObject() 函数访问此内存吗?

我确定这可能是一个非常基本的问题,但我们将不胜感激任何帮助!

原始 对象仍然有效使用 - 因为它仍然由给定变量命名,请继续使用它。新对象 not 创建,现有对象 not 失效。所以,是的,代码将是 "operating on the pinned area of memory".

GCHandle.Alloc(.., GCHandleType.Pinned) 的行为是:

  • 在调用 Free 之前无法对对象进行 GC,即使它不再是强可达的。如果句柄是 'forgotten'.

  • ,这可能会导致 [true] 内存泄漏
  • 对象不能在 GC 压缩循环中移动,也不能在 GC 代之间移动。这会导致减少 GC performance/efficiency.