//示例程序(详情https://alexatnet.com/articles/memory-leaks-in-net-applications/large-object-heap-fragmentation)
class Program
{
private static List<byte[]> _arrays = new List<byte[]>();
static void Main(string[] args)
{
Console.WriteLine("Press any key to start allocations.");
Console.ReadLine();
var index = 0;
var size = 8 * 1024 * 1024; // 8Mb
var dsize = 7 * 1024 * 1024; // 7Mb
while (true)
{
// Create object that allocated in the beginning of the heap segment:
var local = new byte[dsize];
// Next allocated object will be placed next to it:
_arrays.Add(new byte[size]);
// Destory first object:
local = null;
//System.Runtime.GCSettings.LargeObjectHeapCompactionMode = System.Runtime.GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();
//GC.Collect(2);
// At this point heap segment has a free space of “dsize” bytes
// at the beginning and object of “size” bytes after it:
// [ ... free, ~7Mb ... ][ ....... 8Mb .......] - 16 Mb total
// Increase the dynamic size so the next allocated object
// does not fit in any free region:
dsize += 100;
index++;
Console.WriteLine("Iteration {0}: press any key to continue.", index);
Console.ReadLine();
}
Console.ReadLine();
}
两个输出均基于10次迭代。
0:006> !dumpheap 04401000 Address MT Size 04401000 00ee2d38 10 Free 04401010 00ee2d38 14 Free 04401020 72eadc28 4708 04402288 00ee2d38 14 Free 04402298 72eadc28 524 044024a8 00ee2d38 14 Free 044024b8 72eadc28 4092 044034b8 00ee2d38 14 Free 044034c8 72eadc28 8172 044054b8 00ee2d38 7340078 Free 04b054e8 72eb2518 8388620 05401000 00ee2d38 7340174 Free 05b01090 72eb2518 8388620 06401000 00ee2d38 7340278 Free 06b010f8 72eb2518 8388620 07401000 00ee2d38 7340374 Free 07b01158 72eb2518 8388620 08651000 00ee2d38 7340478 Free 08d511c0 72eb2518 8388620 09651000 00ee2d38 7340574 Free 09d51220 72eb2518 8388620 0a651000 00ee2d38 7340678 Free 0ad51288 72eb2518 8388620 0bae1000 00ee2d38 7340774 Free 0c1e12e8 72eb2518 8388620 0cae1000 00ee2d38 7340878 Free 0d1e1350 72eb2518 8388620 0dae1000 00ee2d38 7340974 Free 0e1e13b0 72eb2518 8388620 Statistics: MT Count TotalSize Class Name 72eadc28 4 17496 System.Object[] 00ee2d38 15 73405326 Free 72eb2518 10 83886200 System.Byte[] Total 29 objects
0:006> !dumpheap 031f1000 Address MT Size 031f1000 00652d98 10 Free 031f1010 00652d98 14 Free 031f1020 72eadc28 4708 031f2288 00652d98 14 Free 031f2298 72eadc28 524 031f24a8 00652d98 14 Free 031f24b8 72eadc28 4092 031f34b8 00652d98 14 Free 031f34c8 72eadc28 8172 031f54b8 00652d98 14 Free 031f54c8 72eb2518 8388620 047d1000 00652d98 14 Free 047d1010 72eb2518 8388620 05901000 00652d98 14 Free 05901010 72eb2518 8388620 06b51000 00652d98 14 Free 06b51010 72eb2518 8388620 07b51000 00652d98 14 Free 07b51010 72eb2518 8388620 08b51000 00652d98 14 Free 08b51010 72eb2518 8388620 09b51000 00652d98 14 Free 09b51010 72eb2518 8388620 0afe1000 00652d98 14 Free 0afe1010 72eb2518 8388620 0bfe1000 00652d98 14 Free 0bfe1010 72eb2518 8388620 0cfe1000 00652d98 14 Free 0cfe1010 72eb2518 8388620 Statistics: MT Count TotalSize Class Name 00652d98 15 206 Free 72eadc28 4 17496 System.Object[] 72eb2518 10 83886200 System.Byte[] Total 29 objects
现在我有以下困惑。
测试:32位应用程序。
即使我们设置了LOH Compaction设置,为什么还要 14 Free ?出于什么目的,它在那里保留了14个免费?
如果你在32位应用程序上运行115或116次迭代这个程序会抛出内存不足吗?那么为什么设置LargeObjectHeapCompactionMode没有任何区别呢?