我正在使用 Red Gates ANTS 内存分析器来调试内存泄漏。它一直警告我:
内存碎片可能导致 .NET 保留过多的可用内存。
或者
内存碎片正在影响可以分配的最大对象的大小
因为我有强迫症,这个问题必须解决。
有哪些标准编码实践有助于避免内存碎片。你能通过一些.NET 方法对其进行碎片整理吗?它甚至会有所帮助吗?
我正在使用 Red Gates ANTS 内存分析器来调试内存泄漏。它一直警告我:
内存碎片可能导致 .NET 保留过多的可用内存。
或者
内存碎片正在影响可以分配的最大对象的大小
因为我有强迫症,这个问题必须解决。
有哪些标准编码实践有助于避免内存碎片。你能通过一些.NET 方法对其进行碎片整理吗?它甚至会有所帮助吗?
你知道,我有点怀疑这里的内存分析器。.NET 中的内存管理系统实际上试图通过在内存中移动来为您整理堆碎片(这就是为什么您需要固定内存以使其与外部 DLL 共享)。
占用较长时间的大内存分配容易产生更多碎片。虽然小的临时(短)内存请求不太可能导致 .NET 中的碎片。
这也是值得思考的事情。在 .NET 的当前 GC 中,分配的内存在时间上很接近,通常在空间上间隔很近。这与碎片化相反。即您应该按照您打算访问它的方式分配内存。
它是仅托管代码还是包含 P/Invoke、非托管内存 (Marshal.AllocHGlobal) 或 GCHandle.Alloc(obj, GCHandleType.Pinned) 之类的东西?
GC 堆以不同的方式处理大对象分配。它不会压缩它们,而只是组合相邻的空闲块(如传统的非托管内存存储)。
更多信息在这里:http: //msdn.microsoft.com/en-us/magazine/cc534993.aspx
因此,对于非常大的对象,最好的策略是分配一次,然后保留并重用它们。
.NET Framework 4.5.1 能够在垃圾回收期间显式压缩大对象堆 (LOH)。
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();