2012-07-22 63 views
1

有什么办法可以告诉 .net运行时,而不是重新定位内存中的对象?对象内存重定位?

恕我直言 - 对象可以重新定位由GC时:从一代转移到另一个

    • finilization-queue移动到f-reachable队列。
    • else(也许是优化机制?)。

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

    (只是一个theoratical问题)

  • +2

    这是什么意思?在* regular * c#中,对象位置是一个对我们来说不可行的实现细节....你在做什么*做*? – 2012-07-22 09:40:35

    +1

    不可变对象不被“重新创建”,不变性不影响对象是否将被重新定位。 – Lee 2012-07-22 09:55:40

    +0

    @MarcGravell刚刚学习我的朋友,只是学习。 – 2012-07-22 10:04:20

    回答

    3

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

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

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

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

    +0

    你是对的,我错了,认为对象从1队列移动到另一个,_pointer_被删除。感谢您的纠正。 – 2012-07-22 10:09:29

    +0

    svick有2个HEAPS(1个用于大物体,另一个用于小物体)的事实呢?对象是否可以从一个移动到另一个(如果修改)? – 2012-07-22 10:21:45

    +1

    对象的大小永远不会改变,因此移动到大对象堆或从大对象堆移动没有多大意义,也不会发生。 LOH有用的原因之一是其中的对象不会移动(尽管您不应该依赖这个对象并且也可以使用钉住大对象)。 – svick 2012-07-22 10:27:16

    0

    不知道这是问题的情况下是有用的,但在管理的情况下,你可以使用Marshall类来分配内存,移动结构,分配的内存,并得到一个指针回来。这个结构不会被gc移动。稍后,您可以使用之前的指针从分配的内存中检索结构。

    1

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

    有用的情景

    让我们有需要传递给一些非托管函数阵列的int和非托管函数读取阵列的价值,并做一些变化情景的想法。如果数组未固定,则更改后的值将无法写回,因为指针已移至GC。

    +0

    +1:之前从未听说过该关键字。 – 2012-07-22 10:08:02