嵌套的“fixed”语句

3
根据 C#参考文献 中关于 fixed 语句的说明:

fixed 语句防止垃圾回收器重新定位可移动变量。 ... 在执行语句中的代码后,任何固定的变量都会被取消固定并且可能被垃圾回收。因此,请勿在 fixed 语句之外指向这些变量。

本页未提及的是:如果我们为同一变量嵌套使用 fixed 语句会发生什么?
var data = new byte[100];
unsafe
{
    fixed(byte* pData = data)
    {
        //pData points to the "pinned" variable
        fixed(byte* pData2 = data)
        {
            //pData points to the "pinned" variable
            //pData2 points to the "pinned" variable
        }
        //Does pData still point to the "pinned" variable?
    }
}

上面的代码仅供示例。实际应用可能需要使用递归函数。

参见:https://dev59.com/MHVC5IYBdhLWcg3w4Vf6 - Rekshino
1个回答

6

这个操作的效果与你预期的一样,它是必要的。"fixed"属性与指针变量相关联,而不是与它所钉住的对象相关联。因此,在内部作用域块中,有两个固定了数组的变量。在上面一层,只有一个变量固定了它。它仍然被固定。

当你递归,且数组在方法外声明时,那么将会有更多的变量固定它。

理解该操作的一个良好思路是假设"fixed"初始化了对象的GCHandle。你可以为一个对象创建尽可能多的GCHandles,GC并不会介意。但实际运行时并没有这么多,"fixed"比GCHandle更加高效。它是变量的一个属性,在像ildasm.exe这样的反汇编器中显示为[pinned]。当GC遍历栈寻找对象引用时,会发现该属性。


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