1

有没有办法告诉.net 运行时,而不是在内存中重新定位对象?

恕我直言 - 对象可以在以下时间重新定位GC

  • 从一代到另一代
  • 被移到队列中finilization-queuef-reachable
  • 否则(也许是优化机制?)。

    另外,我认为不可变(字符串)每次都会自动重新创建,因此必须在新位置创建它们。

(只是一个理论问题)

4

3 回答 3

3

作为一个实现细节,.Net 框架可以在垃圾回收的最后阶段移动内存中的对象。但这并不一定意味着在世代之间移动:在执行第 2 代 GC 时,第 2 代中的对象将被移动,即使它们不会改变世代(因为没有地方可以超越第 2 代)。

finalization queue 和 f-reachable queue 与此无关,它们只包含对对象的引用,而不是对象本身。

我不知道这与不可变对象有什么关系。运行时不会对它们进行任何特殊处理(字符串除外)。

告诉运行时不要重定位对象(也称为“固定”对象)是一个不寻常的要求,应该有一个非常好的理由,因为它会对 GC 的性能产生负面影响。要在不安全代码中临时固定对象,可以使用fixed语句. 要永久执行此操作或从安全代码执行此操作,您可以使用GCHandle.Alloc(), 指定GCHandleType.Pinned.

于 2012-07-22T09:56:09.267 回答
1

固定对象告诉 gc 不要移动它以创建大量可用空间。它们是使用Fixed关键字创建的。

有用的场景

让我们考虑一个场景,我们需要将一个 int 数组传递给某个非托管函数,并且非托管函数读取数组的值并进行一些更改。如果数组未固定,则更改的值将无法写回,因为指向数组的指针已被 GC 移动。

于 2012-07-22T09:38:57.327 回答
0

不确定这在问题上下文中是否有用,但在托管场景中,您可以使用Marshall类来分配内存,将结构移动到分配的内存并取回指针。这个结构不会被 gc 移动。稍后您可以使用之前的指针从分配的内存中检索结构。

于 2012-07-22T09:34:03.707 回答