【问题标题】:Large Object Heap Compaction, when is it good?Large Object Heap Compaction,什么时候好?
【发布时间】:2013-11-30 21:08:33
【问题描述】:

首先,多大才算大?有没有办法确定一个对象在堆中有多大?

.Net 4.5.1 自带这个LargeObjectHeapCompactionMode

LargeObjectHeapCompactionMode 属性设置为之后 GCLargeObjectHeapCompactionMode.CompactOnce,下一次全阻塞 垃圾收集(和 LOH 的压缩)发生在 未来时间不确定。您可以通过以下方式立即压缩 LOH 使用如下代码:

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

据我所知,压缩 LOH 是一件坏事!那么,哪一个最差?紧凑 LOH 还是存在 LOH 碎片?

【问题讨论】:

  • 除非你真的有问题,否则不要担心 GC。手动摆弄 GC 几乎不会带来任何好处。
  • @HansPassant 哈哈哈......性能方面,对于非脾气暴躁的程序员来说,真的那么糟糕吗?
  • 没有好坏之分;这是一个权衡。如果您的应用程序由于 LOH 碎片而运行到 OOM,则在某些情况下压缩 LOH 并从您的应用程序中挤出额外的运行时间可能会更好。另一个选项(并且,在 .NET 4.5 之前,唯一的选项)是在 LOH 变得过于分散时重新启动应用程序。您将需要分析使用和不使用 LOH 压缩的应用程序以确定性能影响。 (我想另一种选择是避免创建大型对象,例如,如果您处理大型数组,则可以对它们进行分段,但是.. ugh)。

标签: c# .net memory-management .net-4.5


【解决方案1】:

分配 >= 85 KB 进入 LOH。压缩 LOH 也不错——只是 LOH 碎片并不是大多数应用程序需要担心的问题,因此对于他们来说,不值得为压缩而付出代价。

当您分配几个大对象并且它们都从同一地址空间页面中获取时,就会发生碎片,然后让其中一些对象被收集。该页面中剩余的可用空间可能因为太小而无法使用,或者甚至只是“被遗忘”,因为分配器不会重新考虑再次使用它。

最终,要使用的干净页面越来越少,因此分配器将开始减速,因为它强制移动对象甚至开始抛出 OutOfMemory 异常。压缩将这些对象移动到新页面,回收空闲空间。

您的应用是否有这种对象使用模式?大多数没有。在 64 位平台上,您甚至可能不会注意到它,因为在它成为一个大问题之前,还有相当多的地址空间需要分段。

【讨论】:

  • 优秀的答案。我已经看到 OutOfMemoryException 经常出现在 ASP.NET Web 应用程序上,这些应用程序由于 LOH 碎片(使用 WinDbg 验证)而不会经常(或永远)回收。 (当然,这在 32 位应用程序中发生得更快。)例如,具有大型/复杂表单(并且使用 Viewstate)的 ASP.NET 应用程序通常会生成超过 85 KB 的 ViewState 字符串。过去,我的解决方案是设置回收计划和编码应用程序,以使用户不会注意到回收应用程序池的方式(例如,不会以失去工作的方式终止他们的会话)。最后,一个 LOH 紧凑的功能!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-01
  • 2011-09-27
相关资源
最近更新 更多