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

时间:2011-03-09 03:07:55

标签: c# .net memory-management memory-leaks fragmentation

我正在使用Red Gates ANTS内存分析器来调试内存泄漏。它一直警告我:

  

可能导致内存碎片化   .NET可以保留过多的可用内存。

  

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

因为我有强迫症,所以必须解决这个问题。

哪些标准编码实践有助于避免内存碎片。 你能通过一些.NET方法对它进行碎片整理吗?它会帮助吗?

3 个答案:

答案 0 :(得分:10)

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

此处有更多信息:http://msdn.microsoft.com/en-us/magazine/cc534993.aspx

因此,使用非常大的对象的最佳策略是分配它们一次,然后保持它们并重复使用它们。

答案 1 :(得分:9)

你知道,我有点怀疑这里的内存分析器。 .NET中的内存管理系统实际上是通过在内存中移动来尝试对堆进行碎片整理(这就是为什么需要固定内存以便与外部DLL共享)。

在较长时间内进行的大量内存分配容易产生更多碎片。虽然小的短暂(短)内存请求不太可能导致.NET碎片化。

这也是值得思考的事情。使用.NET的当前GC,及时分配的内存通常在空间中间隔很近。这与碎片相反。即你应该按照打算访问它的方式分配内存。

它只是托管代码还是包含P / Invoke,非托管内存(Marshal.AllocHGlobal)或GCHandle.Alloc(obj,GCHandleType.Pinned)等内容?

答案 2 :(得分:7)

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

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

GCSettings.LargeObjectHeapCompactionMode

中查看更多信息