Может ли фрагментация кучи больших объектов вызвать OutOfMemory в 64-битных процессах?

Я готовлю презентацию для моей команды по.net GC и памяти. Различные источники обсуждают потенциальное влияние фрагментации на кучу больших объектов. Так как это было бы интересно показать, я пытаюсь показать это в коде.

Томас Веллер предложил этот код, который выглядит так, как будто он должен вызывать OOM при попытке выделить больший объект в освобожденные пробелы в LOH, но по какой-то причине этого не происходит. LOH автоматически сжимается в.net 4.6? Разве фрагментация LOH просто не проблема в 64-битной версии?

источник: /questions/12355839/fragmentatsiya-loh-obnovlenie-2015-goda/12355847#12355847

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();
        }
    }
}
}

2 ответа

Начиная с.NET 4.5.1 (также.NET Core) поддерживается сжатие LOH, и поведение может быть установлено GCSettings.LargeObjectHeapCompactionMode свойство статического класса GcSettings.

Это означает, что LOH уплотнен GC.

Имейте в виду, что 32-битный процесс имеет некоторые ограничения на объем используемой памяти, поэтому он с большей вероятностью столкнется с исключением OOM.

Я думаю, что LOH не будет компактным автоматически.

Поскольку компактный LOH влияет на производительность, мы должны делать это, когда знаем это наверняка.

С этим кодом он скоро исчерпает память, компактное действие только перезаписывает объект, на который не ссылаются

Другие вопросы по тегам