我从旧的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
相同的方式删除?
答案 0 :(得分:4)
类型byte[]
看起来类似于stackalloc byte[100]
,但它代表了完全不同的东西。 byte[]
将引用保存到类型派生自System.Array
的堆对象的实例,而stackalloc byte[100]
(并且,就此而言fixed byte[100];
})拥有100个字节。期望类型byte[]
的代码只接受堆对象引用;它不会直接接受100个字节。与所有引用类型一样,只要引用本身存在,就保证存在任何类型引用的System.Array
实例(如果发现某个对象只能通过弱引用访问,那么这些引用将是在对象不再存在之前失效,以便维持这个不变量)。如果没有对数组的引用存储在当前堆栈帧之外的任何位置,它将在堆栈帧退出后停止存在,但如果引用存储在其他位置,则只要任何引用,该数组将存活。
答案 1 :(得分:1)
孤立字节确实是值类型,但数组是引用类型。这里指向managed
的指针存储在堆栈中,与整个unmanaged
变量相同,但在垃圾收集器运行之前,数据所消耗的内存不会被回收。