Stackalloc和值类型

时间:2014-04-22 20:02:27

标签: c# memory-management stack stackalloc

我从旧的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相同的方式删除?

2 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:1)

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