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

C# 大对象堆压缩,什么时候好?,c#,.net,memory-management,.net-4.5,C#,.net,Memory Management,.net 4.5,首先,多大才算大?是否有方法确定堆中的对象有多大 .Net 4.5.1附带此大对象压缩模式: 将LargeObjectHeapCompactionMode属性设置为 GCLargeObjectHeapCompactionMode.CompactOnce,下一个完全阻塞 垃圾收集(和LOH压缩)发生在 不确定的未来时间。您可以通过以下方式立即压缩LOH: 使用如下代码: GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapComp

首先,多大才算大?是否有方法确定堆中的对象有多大

.Net 4.5.1附带此
大对象压缩模式

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

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

据我所知,压缩LOH是件坏事!那么,哪一个最差?压缩LOH或具有LOH碎片?

分配>=85 KB进入LOH。压缩LOH并不坏——只是LOH碎片化不是大多数应用程序需要担心的问题,所以对于他们来说,压缩LOH的费用是不值得的

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

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


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

除非您真的有问题,否则不要担心GC。手动摆弄GC几乎不会带来任何好处。@HansPassant哈哈哈……性能方面,对于不爱胡思乱想的程序员来说,真的有那么糟糕吗?不坏也不好;这是一种权衡。如果你有一个应用程序由于LOH碎片化而运行到OOM中,在某些情况下,压缩LOH并从你的应用程序中挤出一点额外的运行时间可能会更好。另一个选择(在.NET4.5之前,也是唯一的选择)是在LOH变得太零碎时重新启动应用程序。您需要对应用程序进行LOH压缩和非LOH压缩,以确定性能影响。(我想另一个选择是避免创建大型对象,例如,如果您处理大型数组,您可以对它们进行分段,但是..呃)。回答得很好。我见过OutOfMemoryException经常出现在ASP.NET web应用程序上,这些应用程序由于LOH碎片(通过WinDbg验证)而不经常(或永远)回收。(当然,这在32位应用程序中出现得更快。)例如,具有大型/复杂表单(并且使用Viewstate)的ASP.NET应用程序通常会生成超过85 KB的Viewstate字符串。在过去,我的解决方案是设置一个回收计划,并以这样的方式对应用程序进行编码,即回收应用程序池不会引起用户的注意(例如,不会以导致用户丢失工作的方式终止会话)。最后,一个LOH精简功能!