有没有办法告诉 .net运行时,不重新定位内存中的对象?
恕我直言 - 在GC
时,可以通过以下方式重新定位对象:
finilization-queue
移至f-reachable
队列。 else(也许是优化机制?)。
此外,我认为每次都会自动重新创建不可变(字符串),因此必须在新位置创建它们。
(只是一个理论问题)
答案 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移动。稍后,您可以使用之前的指针从已分配的内存中检索结构。