51

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

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

或者

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

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

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

4

3 回答 3

11

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

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

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

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

于 2011-03-09T09:12:18.627 回答
10

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

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

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

于 2011-03-09T09:22:21.417 回答
9

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

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

在GCSettings.LargeObjectHeapCompactionMode中查看更多信息

于 2015-01-02T07:17:33.093 回答