【问题标题】:Force .NET GC to compact or defragment generation 2 heap?强制 .NET GC 压缩或整理第 2 代堆?
【发布时间】:2017-01-06 19:05:54
【问题描述】:

我们在 .NET 框架中使用 C# 编写了一个 Windows 服务,几个小时后我们注意到第 2 代堆的大小变得异常。 其中大部分空间是免费的,dotMemory Profiler 向我们展示了这一代我们有大约 90% 的碎片。 如何强制 .NET GC 压缩这个空间?这意味着 GC 可以释放这个空间,但它不能压缩它以供进一步使用。

【问题讨论】:

  • afaik GC 在您尝试分配新内存时自动对其进行碎片整理,并且它意识到没有足够大的块。除非您遇到真正的问题(例如,碎片整理最终发生时花费了太多时间),否则您不应该自己解决这个问题。
  • 您必须深入挖掘。当您的程序中的对象被固定很长时间时,就会发生这种情况。或者,如果终结器线程已死锁。
  • @RenéVogt 我遇到了这个不寻常的增长大小的真正问题!所以我决定自己处理。我看到大约 2G generation 2 Heap 但只使用了大约 30M,其余的都是零散的和免费的。
  • 什么版本的.net framework - GC在4.5发生了变化
  • 我们的 windows 服务有内存泄漏,通过处理这些缓冲区,我们解决了这个问题。所以,我们不需要任何其他碎片整理。

标签: c# .net garbage-collection defragmentation heap-fragmentation


【解决方案1】:

第 2 代堆是小对象堆,所以基本上第 2 代也会压缩(因为我们调用了 GC.Collect())

而且大对象堆(>=85K) 不会自动压缩。 我要压缩LOH,可以用.Net Framework。

所以要确定你使用的是哪个堆~

【讨论】:

    【解决方案2】:

    由于 0,1,2 代会被 GC 自己压缩和删除,

    猜测对象分配在大对象堆上(LOH, Object size >= 85K)

    那么,你可以试试LargeObjectHeapCompactionMode,它可以compact loh

    GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
    GC.Collect();  
    

    参考:MSDN

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多