大对象堆压缩,什么时候好?

Kam*_*eri 10 .net c# memory-management .net-4.5

首先,有多大被认为是大的?反正有没有确定一个对象在堆中的大小?

.Net 4.5.1附带LargeObjectHeapCompactionMode:

在将LargeObjectHeapCompactionMode属性设置为GCLargeObjectHeapCompactionMode.CompactOnce之后,下一个完全阻塞垃圾收集(以及LOH的压缩)将在不确定的未来时间发生.您可以使用以下代码立即压缩LOH:

GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();      
Run Code Online (Sandbox Code Playgroud)

据我所知,压缩LOH是件坏事!那么哪一个最差?紧凑型LOH或LOH碎裂?

Cor*_*son 8

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

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

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

您的应用是否具有此对象使用模式?大多数人没有.在64位平台上,您可能甚至都没有注意到它,因为在它变成一个巨大的问题之前,要分割的地址空间要多得多.

  • 很好的答案.我已经看到OutOfMemoryException经常出现在ASP.NET Web应用程序上,这些应用程序由于LOH碎片而不经常(或永远)回收(使用WinDbg验证).(当然,这在32位应用程序中会更早出现.)例如,具有大型/复杂表单(并且使用Viewstate)的ASP.NET应用程序通常会生成超过85 KB的ViewState字符串.在过去,我的解决方案是设置回收计划和代码应用程序,以便回收应用程序池对用户来说不明显(例如,没有以他们丢失工作的方式杀死他们的会话).最后,LOH紧凑功能! (2认同)