我想了解在C#中完整地使用堆的完整工作。我理解堆栈和堆的工作方式,但是我没有发现堆碎片整理的任何解释(如果可能的话)。c#中的堆碎片整理?
当GC正在分配和释放堆上的内存块时,我读了很多关于碎片问题的文章。
所以,如果有人可以向我解释或提供一些关于此问题和堆(内存)碎片整理的好文章。
我想了解在C#中完整地使用堆的完整工作。我理解堆栈和堆的工作方式,但是我没有发现堆碎片整理的任何解释(如果可能的话)。c#中的堆碎片整理?
当GC正在分配和释放堆上的内存块时,我读了很多关于碎片问题的文章。
所以,如果有人可以向我解释或提供一些关于此问题和堆(内存)碎片整理的好文章。
如果你知道堆的工作原理,我假设你知道有几种不同类型的堆。看到我的答案在这里 - Stack vs. Heap in .NET
所以你说的那两个我在那个答案中提到的是大对象堆(LOH)和GC堆(也称为Ephemeral堆)。
通常不需要担心.NET的堆碎片。用于.NET的GC工作分3步:标记,扫描,压缩。标记 - 扫描所有根源参考,并列出那些为为根源的列表 - 这些列表不符合垃圾收集条件,不会被触及。扫描 - 清除不在列表中的项目的内存,并清除已标记项目的“标记位”。压缩 - 移动剩余的根目标对象的内存,使其位于连续的块中。紧凑阶段的一个警告是,LOH至少不是.NET 4.6.2的最新版本。这是CLR GC团队做出的设计决策,因为性能原因以及将所有内存移动到连续块的时间。从.NET 1.0开始,性能得到了很多改进,所以GC不是过去的野兽。在任何情况下,堆0,1和2 都是压缩。因此,不用担心那里的碎片。大部分情况下,LOH在其实现的算法中没有碎片问题而存活。有些情况下,你可以在LOH上分解。这可能是由几件事引起的 - 其中一些是错误的分配模式,频繁的Full GC集合等。这可以通过改善分配模式,尽可能地分配大块内存(以编程方式)和对象池来克服。
由于.NET 4.5.1中,有一个手动压缩蕙虽然我会强烈建议反对,理由是它是为您的应用巨大的性能命中原因有二道:
信息关于GC标志,清扫,紧凑 - https://blogs.msdn.microsoft.com/abhinaba/2009/01/30/back-to-basics-mark-and-sweep-garbage-collection/
信息约LOH分配算法: https://www.red-gate.com/simple-talk/dotnet/net-framework/the-dangers-of-the-large-object-heap/
从[CLR via C#]开始(https://blogs.msdn.microsoft.com/microsoft_press/2012/11/29/new-book-clr-via-c-fourth-edition/)。 –