“Pinned GC handle”的概念是什么?

13

当我们分析内存堆时,通常会遇到以下4种类型的GC句柄:

  1. 弱引用:弱引用GC句柄不会阻止其对应的实例被垃圾回收。例如,System.WeakReference类的实例使用此类句柄

  2. 正常引用:正常引用GC句柄会阻止相应的实例被垃圾回收。例如,强引用的实例使用此类句柄

  3. 引用计数:引用计数GC句柄在运行时内部使用,例如处理COM接口时

  4. 固定引用:为什么需要这种GC句柄?是仅为了避免该实例在内存中移动还是背后还有其他概念?我想知道固定引用GC句柄背后的概念(并附带示例)。

编辑为Itay的答案:我有一个非空数组-DiffCell [][ ]绑定到WPF中的数据网格。当我关闭显示此数据网格的窗口时,在堆上通过object [] 看到指向此空的DiffCell数组的固定引用GC句柄(请参见快照)。我没有使用任何不安全的代码。在关闭该窗口之前,我只是将数据网格的ItemsSource设置为null。那么我的问题是,谁会在堆上固定此数组以及为什么?

alt text

2个回答

7

如果我们使用指针,那么我们就需要这个操作。

想象一下,你声明了一个指针指向一个内存地址,但是你没有固定它。

垃圾回收机制有时会将内存块移动到其他位置,因此您的指针将无效。

举个例子:

public unsafe void DoSomething(byte b)
{
   byte * bp = &b;
}

这段代码无法编译,因为您没有修复保存字节的内存位置。
为了固定它,您可以使用:

public unsafe void DoSomething(byte b)
{
   fixed(byte * bp = &b)
   {
        //do something
   }
}

谢谢Itay!请查看修改后的问题并告诉我您的意见。 - Kushal Waikar
我真的不太了解WPF和绑定是如何工作的,所以恐怕我无法在这方面帮助你。 - Itay Karo

3
不要忘记GCHandle,它支持固定对象(并检索地址作为IntPtr)。固定对象不仅限于不安全代码(fixed语句)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接