对象内存重新定位?

时间:2012-07-22 09:29:49

标签: c# .net memory-management .net-4.0 clr

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

恕我直言 - 在GC时,可以通过以下方式重新定位对象:

  • 从一代迁移到另一代
  • finilization-queue移至f-reachable队列。
  • else(也许是优化机制?)。

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

(只是一个理论问题)

3 个答案:

答案 0 :(得分:3)

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

终结队列和f-reachable队列与此无关,它们只包含对象的引用,而不包含对象本身。

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

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

答案 1 :(得分:1)

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

有用的方案

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

答案 2 :(得分:0)

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