3

我从较早的 StackOverflow 帖子中阅读了一个关于何时使用 stackalloc 的示例。现在这个例子让我有点困惑:

public unsafe void DoSomeStuff()
{
    byte* unmanaged = stackalloc byte[100];
    byte[] managed = new byte[100];

    //Do stuff with the arrays

    //When this method exits, the unmanaged array gets immediately destroyed.
    //The managed array no longer has any handles to it, so it will get 
    //cleaned up the next time the garbage collector runs.
    //In the mean-time, it is still consuming memory and adding to the list of crap
    //the garbage collector needs to keep track of. If you're doing XNA dev on the
    //Xbox 360, this can be especially bad.
}

现在,如果我错了,请随时纠正我,因为我还是 C# 和一般编程的新手。但是字节不是值类型吗?值类型不是存储在声明它们的地方吗?这是否意味着在此示例中,managed也存储在堆栈中,并且通过扩展,当此堆栈帧完成并转到调用地址时,内存会自动清理,因此应该以与此managed相同的方式删除unmanaged例子?

4

2 回答 2

4

类型byte[]看起来类似于stackalloc byte[100],但它代表完全不同的东西。Abyte[]持有对类型派生自 的堆对象实例的引用System.Array,而 a stackalloc byte[100](并且,就此而言 a fixed byte[100];)持有 100 个字节。期望某种类型的代码byte[]将只接受堆对象引用;它不会直接接受 100 个字节。与所有引用类型一样,aSystem.Array只要引用本身存在,就保证存在任何类型引用的实例存在(如果发现对象只能通过弱引用访问,则这些引用将在对象停止存在之前失效,以维护这个不变量)。如果在当前堆栈帧之外的任何地方都没有存储对数组的引用,则堆栈帧退出后它将不复存在,但如果引用存储在其他位置,则数组将与任何引用一样存在。

于 2014-04-22T20:34:00.677 回答
1

独立字节确实是值类型,但数组是引用类型。指向managed此处的指针存储在堆栈中,与整个unmanaged变量相同,但数组消耗的内存在垃圾收集器运行之前不会被回收。

于 2014-04-22T20:07:50.863 回答