GCHandle固定的内存/对象数量达到多少会使垃圾回收器变慢?

5
我确定这个答案会依赖于用户的机器,但有一些固定的最佳实践可以用来锁定数据。

我需要保存5个包含1048576个字节的数组。通常情况下,我更喜欢使用GCHandle(受管)内存,但有人说它会减慢GC的速度。我知道这可能发生,但是要锁定多少内存/对象才会真正影响GC呢?

以下是我的选择:

  1. GCHandle.Alloc GCHandleType.Pinned (managed). 它会减慢GC吗??
  2. Marshal.AllocHGlobal (unmanaged acess). 不安全的代码
  3. 使用Bitmap在Scan0中保存数据(未受管访问)。不安全的代码

1
将五个每个一兆字节的分配固定不会对GC或其他任何事情产生影响。为什么不试试呢?我强烈怀疑它会很好地工作。我也严重怀疑使用您列出的任何一种替代方案都不会显着更快或更慢。 - Jim Mischel
1个回答

5
这是一个无法回答的问题。固定对象并不会使GC变慢,只是在GC压缩堆时会阻碍一下。可以很容易地通过跳过固定的堆段来避开这个障碍。更糟糕的情况是,它会对收集完成后运行的代码产生持久影响。由于堆没有被压缩得那么好,引用的局部性不太好,因此处理器无法从CPU缓存中获得足够的优势。无法量化这种减速,它非常依赖于之后运行的代码类型。唯一确定的是它更糟糕,并且持续了一段时间,直到下一个GC。
唯一的建议是,如果必须固定,则尽可能短地固定。并且避免在对象被固定时发生收集的情况。这大致意味着在持有固定时避免分配内存。如果程序正在运行多个线程,则这并不总是实际可行的,这时在.config文件中使用元素比较有吸引力。它选择了一种不同的GC策略,使用了更多的内存,但为线程提供了自己的GC堆片段。没有简单的指导来确定何时执行此操作,需要使用真实数据集进行分析。
Marshal.AllocHGlobal和Bitmap对GC堆没有任何显着影响,它们从非托管内存堆中分配。

谢谢,你知道关于这个主题的任何文章吗? - Pedro77
我不提供链接,谷歌比我更擅长。任何一本像样的.NET书都会讲到垃圾回收器。没有人会对Richter的CLR via C#感到失望。 - Hans Passant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接