简体   繁体   English

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

[英]What causes memory fragmentation in .NET

I am using Red Gates ANTS memory profiler to debug a memory leak. 我正在使用Red Gates ANTS内存分析器来调试内存泄漏。 It keeps warning me that: 它一直警告我:

Memory Fragmentation may be causing .NET to reserver too much free memory. 内存碎片可能导致.NET保留过多的可用内存。

or 要么

Memory Fragmentation is affecting the size of the largest object that can be allocated 内存碎片正在影响可以分配的最大对象的大小

Because I have OCD, this problem must be resolved. 因为我有强迫症,所以必须解决这个问题。

What are some standard coding practices that help avoid memory fragmentation. 有哪些标准编码实践有助于避免内存碎片。 Can you defragment it through some .NET methods? 你能通过一些.NET方法对它进行碎片整理吗? Would it even help? 它会帮助吗?

The GC heap treats large object allocations differently. GC堆以不同方式处理大对象分配。 It doesn't compact them, but instead just combines adjacent free blocks (like a traditional unmanaged memory store). 它不会压缩它们,而只是组合相邻的空闲块(就像传统的非托管内存存储区)。

More info here: http://msdn.microsoft.com/en-us/magazine/cc534993.aspx 更多信息: http//msdn.microsoft.com/en-us/magazine/cc534993.aspx

So the best strategy with very large objects is to allocate them once and then hold on to them and reuse them. 因此,使用非常大的对象的最佳策略是分配它们一次然后保持它们并重用它们。

You know, I somewhat doubt the memory profiler here. 你知道,我有点怀疑这里的内存分析器。 The memory management system in .NET actually tries to defragment the heap for you by moving around memory (that's why you need to pin memory for it to be shared with an external DLL). .NET中的内存管理系统实际上是通过在内存中移动来尝试对堆进行碎片整理(这就是为什么需要固定内存以便与外部DLL共享)。

Large memory allocations taken over longer periods of time is prone to more fragmentation. 在较长时间内进行的大量内存分配容易产生更多碎片。 While small ephemeral (short) memory requests are unlikely to cause fragmentation in .NET. 虽然小的短暂(短)内存请求不太可能导致.NET碎片化。

Here's also something worth thinking about. 这也是值得思考的事情。 With the current GC of .NET, memory allocated close in time, is typically spaced close together in space. 使用.NET的当前GC,及时分配的内存通常在空间中间隔很近。 Which is the opposite of fragmentation. 这与碎片相反。 ie You should allocate memory the way you intend to access it. 即您应该按照打算访问它的方式分配内存。

Is it a managed code only or does it contains stuff like P/Invoke, unmanaged memory (Marshal.AllocHGlobal) or stuff like GCHandle.Alloc(obj, GCHandleType.Pinned)? 它只是托管代码还是包含P / Invoke,非托管内存(Marshal.AllocHGlobal)或GCHandle.Alloc(obj,GCHandleType.Pinned)等内容?

The .NET Framework 4.5.1, has the ability to explicitly compact the large object heap (LOH) during garbage collection. .NET Framework 4.5.1能够在垃圾回收期间显式压缩大对象堆(LOH)。

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

See more info in GCSettings.LargeObjectHeapCompactionMode 请在GCSettings.LargeObjectHeapCompactionMode中查看更多信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM