有什么办法可以告诉 .net运行时,而不是重新定位内存中的对象?对象内存重定位?
恕我直言 - 对象可以重新定位由GC
时:从一代转移到另一个
- 从
finilization-queue
移动到f-reachable
队列。 else(也许是优化机制?)。
此外,我认为每次都会自动重新创建不可变(字符串),所以它们必须在新的位置创建。
(只是一个theoratical问题)
有什么办法可以告诉 .net运行时,而不是重新定位内存中的对象?对象内存重定位?
恕我直言 - 对象可以重新定位由GC
时:从一代转移到另一个
finilization-queue
移动到f-reachable
队列。else(也许是优化机制?)。
此外,我认为每次都会自动重新创建不可变(字符串),所以它们必须在新的位置创建。
(只是一个theoratical问题)
作为实现细节,.Net框架可以在垃圾回收的最后阶段移动内存中的对象。但这并不一定意味着代之间的移动:在执行第2代GC时,即使不改变世代(因为无法超越第2代),第2代中的对象也会移动。
最终化队列和f-reachable队列与此无关,它们只包含对象的引用,而不包含对象本身。
我不知道这与不可变对象有什么关系。运行时不会给予任何特殊处理(字符串除外)。
告诉运行时不要重定位一个对象(也称为“固定”对象)是一个不寻常的要求,应该有一个非常好的理由,因为它会对GC的性能产生负面影响。要临时锁定不安全代码中的对象,可以使用the fixed
statement。要永久或从安全代码执行此操作,可以使用GCHandle.Alloc()
,指定GCHandleType.Pinned
。
你是对的,我错了,认为对象从1队列移动到另一个,_pointer_被删除。感谢您的纠正。 – 2012-07-22 10:09:29
svick有2个HEAPS(1个用于大物体,另一个用于小物体)的事实呢?对象是否可以从一个移动到另一个(如果修改)? – 2012-07-22 10:21:45
对象的大小永远不会改变,因此移动到大对象堆或从大对象堆移动没有多大意义,也不会发生。 LOH有用的原因之一是其中的对象不会移动(尽管您不应该依赖这个对象并且也可以使用钉住大对象)。 – svick 2012-07-22 10:27:16
不知道这是问题的情况下是有用的,但在管理的情况下,你可以使用Marshall类来分配内存,移动结构,分配的内存,并得到一个指针回来。这个结构不会被gc移动。稍后,您可以使用之前的指针从分配的内存中检索结构。
固定对象告诉gc不要移动它来创建大量可用空间。它们使用Fixed关键字创建。
有用的情景
让我们有需要传递给一些非托管函数阵列的int和非托管函数读取阵列的价值,并做一些变化情景的想法。如果数组未固定,则更改后的值将无法写回,因为指针已移至GC。
+1:之前从未听说过该关键字。 – 2012-07-22 10:08:02
这是什么意思?在* regular * c#中,对象位置是一个对我们来说不可行的实现细节....你在做什么*做*? – 2012-07-22 09:40:35
不可变对象不被“重新创建”,不变性不影响对象是否将被重新定位。 – Lee 2012-07-22 09:55:40
@MarcGravell刚刚学习我的朋友,只是学习。 – 2012-07-22 10:04:20