什么导致.NET中的内存碎片

我正在使用Red Gates ANTS内存分析器来debugging内存泄漏。 它不断警告我:

内存碎片可能导致.NET预留太多空闲内存。

要么

内存碎片正在影响可以分配的最大对象的大小

因为我有强迫症,这个问题一定要解决。

什么是有助于避免内存碎片的标准编码实践。 你可以通过一些.NET方法进行碎片整理吗? 它甚至会有帮助吗?

你知道,我有点怀疑这里的内存分析器。 .NET中的内存pipe理系统实际上试图通过在内存中移动来为你整理堆(这就是为什么你需要将内存固定到与外部DLL共享的原因)。

较长时间内的大内存分配容易出现更多碎片。 虽然小的短暂(短)内存请求不太可能导致.NET中的碎片。

这里还有一些值得思考的东西。 使用.NET的当前GC,分配的内存时间紧密,通常在空间上紧密排列在一起。 这与碎片化是相反的。 即你应该按照你打算访问它的方式分配内存。

它只是一个托pipe代码,还是包含像P / Invoke,非托pipe内存(Marshal.AllocHGlobal)或像GCHandle.Alloc(obj,GCHandleType.Pinned)之类的东西?

GC堆处理大对象分配的方式不同。 它不会压缩它们,而只是结合相邻的空闲块(如传统的非托pipe内存存储)。

更多信息在这里: http : //msdn.microsoft.com/en-us/magazine/cc534993.aspx

所以对于非常大的对象来说,最好的策略是分配一次,然后保留它们并重用它们。

.NET Framework 4.5.1能够在垃圾收集期间显式压缩大型对象堆(LOH)。

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

在GCSettings.LargeObjectHeapCompactionMode中查看更多信息