C#的垃圾回收器能够移动内存对象吗?

11

让我们假设这是一段非常基础的C#代码:

var tab = new int[10];

我读到过非固定变量可以被垃圾收集器移动在内存中。

我的问题是:在我的程序执行期间,“tab”地址是否可能会改变?

我只是想要理解。

实际上,无论“tab”值是否更改。


跟进问题:你为什么在意?只是感兴趣吗? - Blorgbeard
2
我从未理解这个网站对于像这样的问题的心态?他在问题中提到他只是想了解其基本原理。但几乎每个答案仍然告诉 OP 不重要,他不应该关心。 - David Pilkington
4个回答

12

是的,它会移动。

但是如果你愿意,你可以使用fixed关键字来阻止GC移动它。


10

可以的。变量 tab 的内存地址可能会发生改变(并且很有可能会改变)。参考:ECMA-334 C#语言规范,第 23.4 章节。

重点是,在 C# 中你不必担心内存地址,因为它是一种托管语言。所有对变量 tab 的引用都将相应更改,并且你的程序将在垃圾回收时无缝运行。


3

可以确定数组对象可能在内存中移动。

但请注意,您无法获取托管引用对象的指针,或者使用fixed块,它不能被GC在其中移动。

如果数组对象被移动了,变量tab到数组对象的引用也会被GC固定,因此您将看不到任何受GC影响的内容。


1
考虑到您正在使用var,这意味着您正在一个方法中定义它。您的变量在该方法的上下文中存在时间很短,GC不太可能移动它。
另一方面,GC会移动内存块以减少内存碎片,因此它可能会移动您的变量。最好的部分是,您甚至不会注意到,因为对您来说它仍然是同样的“标签”。
如果您想确保固定该变量的位置,可以使用“fixed”。

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