.net GC とメモリに関するチームへのプレゼンテーションを準備しています。さまざまなソースが、ラージ オブジェクト ヒープに対する断片化の潜在的な影響について議論しています。興味深い現象なので、コードで示してみます。
Thomas Weller は、LOH で解放されたギャップに大きなオブジェクトを割り当てようとすると OOM が発生するように見えるこのコードを提供しましたが、何らかの理由で発生しません。.net 4.6 で LOH は自動的に圧縮されますか? LOH フラグメンテーションは 64 ビットでは問題になりませんか?
ソース: https://stackoverflow.com/a/30361185/3374994
class Program
{
static IList<byte[]> small = new List<byte[]>();
static IList<byte[]> big = new List<byte[]>();
static void Main()
{
int totalMB = 0;
try
{
Console.WriteLine("Allocating memory...");
while (true)
{
big.Add(new byte[10*1024*1024]);
small.Add(new byte[85000-3*IntPtr.Size]);
totalMB += 10;
Console.WriteLine("{0} MB allocated", totalMB);
}
}
catch (OutOfMemoryException)
{
Console.WriteLine("Memory is full now. Attach and debug if you like. Press Enter when done.");
Console.WriteLine("For WinDbg, try `!address -summary` and `!dumpheap -stat`.");
Console.ReadLine();
big.Clear();
GC.Collect();
Console.WriteLine("Lots of memory has been freed. Check again with the same commands.");
Console.ReadLine();
try
{
big.Add(new byte[20*1024*1024]);
}
catch(OutOfMemoryException)
{
Console.WriteLine("It was not possible to allocate 20 MB although {0} MB are free.", totalMB);
Console.ReadLine();
}
}
}
}