【问题标题】:How much GCHandle pinned memory/objects would make Garbage Collector slows down?多少 GCHandle 固定内存/对象会使垃圾收集器变慢?
【发布时间】:2013-06-11 12:26:31
【问题描述】:

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

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

以下是我的选择:

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

【问题讨论】:

  • 固定五个 1 MB 的分配不会对 GC 产生任何影响。或者别的什么,就此而言。为什么不试试呢?我强烈怀疑它会正常工作。我还严重怀疑使用您列出的任何一种替代方案会明显更快或更慢。

标签: c# garbage-collection unmanaged


【解决方案1】:

这是一个无可救药的无法回答的问题。固定对象不会使 GC 减慢太多,当 GC 压缩堆时,它只是路上的一块石头。只需跳过堆的固定部分即可轻松绕过该岩石。

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

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

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

【讨论】:

  • 谢谢,你知道关于这个主题的任何文章吗?
  • 我不做链接,谷歌比我更擅长。任何关于 .NET 的体面书籍都谈到了垃圾收集器。没有人对 Richter 通过 C# 编写的 CLR 感到失望。
猜你喜欢
  • 2021-04-30
  • 2012-01-03
  • 2017-08-22
  • 1970-01-01
  • 1970-01-01
  • 2011-06-18
  • 1970-01-01
  • 2011-09-01
相关资源
最近更新 更多