我读到GC(垃圾回收器)为了性能原因移动堆中的数据,但我不太明白为什么,因为它是随机访问内存,也许是为了更好地顺序访问,但我想知道当堆中发生这种移动时,栈中的引用是否会更新。但也许偏移地址保持不变,而垃圾收集器会移动数据的其他部分,但我不确定。
我认为这个问题涉及实现细节,因为并非所有垃圾收集器都可能执行此类优化,或者它们可能执行该优化但不更新引用(如果这是垃圾收集器实现的通用做法)。但我想得到一些特定于CLR(公共语言运行时)垃圾收集器的整体答案。
我也在阅读Eric Lippert的“References are not addresses”文章here,以下段落有点困惑我:
如果你认为一个引用实际上是一个不透明的GC句柄,那么就变得清楚了, 要找到与句柄相关联的地址,您必须以某种方式“固定”对象。 您必须告诉GC“在进一步通知之前,具有此句柄的对象不得在内存中移动, 因为某人可能拥有它的内部指针”。(有多种方法可以做到这一点,这超出了本文的范围。)
这似乎意味着对于引用类型,我们不希望数据被移动。那么我们可以为了性能优化在堆中移动什么?也许我们在那里存储类型信息?顺便说一下,如果你想知道那篇文章是关于什么的,那么Eric Lippert会稍微比较引用和指针,并尝试解释为什么说引用只是地址可能是错误的,即使这是C#的实现方式。
如果我上面的任何假设是错误的,请纠正我。