我有一个C# 4.0应用程序(单一生产者/单一消费者),它以块的形式传输大量数据。虽然没有新的内存分配,但我会在一段时间后耗尽内存。
我使用Redgate memory profiler分析了内存,那里有很多空闲内存。它说空闲内存不能使用,因为碎片。
我使用一个阻塞集合作为缓冲区,使用字节数组作为成员:
BlockingCollection<byte[]> segments = new BlockingCollection<byte[]>(8);
// producer:
segments.Add(buffer);
// consumer:
byte[] buffer = _segments.Take();
如何避免托管内存碎片?
发布于 2011-04-18 05:03:07
您的byte[]数组有多长?它们属于小对象堆还是大对象堆?如果你经历了记忆碎片,我会说他们落入了LOH。
因此,您应该重用相同的字节数组(使用池)或使用较小的块。LOH永远不会被压缩,因此它可能会变得非常零碎。遗憾的是,没有办法绕过这一点。(除了知道这个限制并避免它之外)
发布于 2018-06-03 12:44:56
GC不会为您压缩大对象堆,您仍然可以通过编程方式压缩它。下面的代码片段说明了如何实现这一点。
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();
https://stackoverflow.com/questions/5696377
复制相似问题