GCHandle固定内存/对象多少会使垃圾收集器变慢?

时间:2013-06-11 12:26:32

标签: c# garbage-collection unmanaged

我确定这个答案取决于用户机器,但必须有一些最佳实践固定数据

我需要保存5个字节数组,每个字节包含1.048.576个字节。通常我更喜欢使用GCHandle(托管)内存,但有些人说它会降低GC的速度。我知道这可能会发生,但需要固定多少内存/对象才能真正影响GC?

以下是我的选项:

  1. GCHandle.Alloc GCHandleType.Pinned(已管理)。它会减慢GC ??
  2. Marshal.AllocHGlobal(非管理访问)。不安全的代码
  3. 使用Bitmap在Scan0中保存数据(非托管访问)。不安全的代码

1 个答案:

答案 0 :(得分:4)

这是一个无可救药的无法解决的问题。固定物体不会对GC造成太大的影响,当GC压缩堆时,它只是路上的一块石头。通过简单地跳过堆的固定部分,可以轻松地在岩石周围工作。

更糟糕的结果是它会在集合完成后对运行的代码产生持久影响。由于堆没有很好地压缩,引用的位置不是那么好,因此处理器将无法从CPU缓存中获得尽可能多的里程数。量化这种减速是不可能的,这在很大程度上取决于之后运行的代码类型。只有它更糟糕并持续一段时间,直到下一个GC。

唯一的好建议是,如果你来固定,那么请尽可能短的时间这样做。并且为了避免在对象被固定的情况下可能发生集合的情况。粗略地说,这意味着您在保持引脚的同时避免分配内存。如果程序运行多个线程,并不总是实用,使.config文件中的<gcServer>元素具有吸引力。它选择使用更多内存的不同GC策略,但为线程提供自己的GC堆段。没有简单的指导来确定何时执行此操作,需要使用实际数据集进行分析。

Marshal.AllocHGlobal和Bitmap都没有对GC堆有任何显着影响,它们是从非托管内存堆中分配的。