Сборщик мусора .NET и виртуальная память x64 - PullRequest
12 голосов
/ 22 июня 2010

Запуск приложения .NET на Windows Server 2008 x64 с 16 ГБ ОЗУ. Это приложение должно извлекать и анализировать очень большой объем данных (около 64 ГБ) и хранить все это в памяти одновременно.

Что я ожидаю увидеть: размер процесса увеличился с 16 ГБ до 64 ГБ. Windows использует виртуальную память для вывода дополнительных данных на диск или с диска по мере необходимости. Это классический вариант использования виртуальной памяти.

Что я на самом деле вижу: Размер процесса ограничен объемом физической памяти (16 ГБ). Приложение тратит 99,8% своего времени на сборщик мусора.

Почему нашему приложению не удается использовать виртуальную память? Это проблема в конфигурации сборщика мусора .NET или в самом диспетчере виртуальной памяти Windows x64? Что я могу сделать, чтобы наше приложение использовало виртуальную память, а не ограничивалось физической памятью?

Спасибо.

- Брайан

Обновление: я написал очень маленькую программу с таким же поведением:

using System;

namespace GCTest
{
    class Program
    {
        static void Main()
        {
            byte[][] arrays = new byte[100000000][];
            for (int i = 0; i < arrays.Length; ++i)
            {
                arrays[i] = new byte[320];
                if (i % 100000 == 0)
                {
                    Console.WriteLine("{0} arrays allocated", i);
                    System.Threading.Thread.Sleep(100);
                }
            }
        }
    }
}

Если вы хотите попробовать это, убедитесь, что вы собрали для x64. Возможно, вам придется немного изменить константы, чтобы усилить нагрузку на вашу систему. Поведение, которое я вижу, состоит в том, что процесс замедляется, когда он приближается к размеру 16 ГБ. Нет сообщения об ошибке или исключение. Монитор производительности сообщает, что% процессорного времени в GC приближается к 100%.

Разве это не неприемлемо? Где система виртуальной памяти?

Ответы [ 2 ]

10 голосов
/ 22 июня 2010

Вы проверили, чтобы убедиться, что ваш файл подкачки настроен так, чтобы он мог расширяться до этого размера?

Обновление

Я играл сэто совсем немного с вашим примером, и вот что я вижу.

Система: Windows 7 64-битная, 6 ГБ трехканальной оперативной памяти, 8 ядер.

  1. ВыВам понадобится дополнительный файл подкачки на другом шпинделе от вашей ОС, иначе такое расследование будет мешать вашей машинеЕсли все борется за один и тот же файл подкачки, это усугубляет ситуацию.

  2. Я вижу большой объем данных, передаваемых из поколения в поколение в GC, плюс большое количествоGC сканирует \ коллекции, и огромное количество сбоев страниц в результате достижения пределов физической памяти.Я могу только предположить, что, когда физическая память исчерпана \ очень высока, что это запускает циклические колебания и продвижения, таким образом вызывая прикосновение к большому количеству выгружаемой памяти, что приводит к смерти spriral, поскольку затронутая память выгружается и другая памятьвытесняется.Все это заканчивается скучным беспорядком.Это кажется неизбежным при выделении большого количества долгоживущих объектов, которые попадают в кучу малых объектов.

Теперь сравните это с размещением объектов в моде, которое будет размещать их непосредственно в куче больших объектов (которая не страдает от тех же проблем с развертыванием и повышением):

private static void Main()
{
    const int MaxNodeCount = 100000000;
    const int LargeObjectSize = (85 * 1000);

    LinkedList<byte[]> list = new LinkedList<byte[]>();

    for (long i = 0; i < MaxNodeCount; ++i)
    {
        list.AddLast(new byte[LargeObjectSize]);

        if (i % 100000 == 0)
        {
            Console.WriteLine("{0:N0} 'approx' extra bytes allocated.",
               ((i + 1) * LargeObjectSize));
        }
    }
}

Это работает, как и ожидалось, т. Е. Виртуальная память используется, а затем в конечном итоге исчерпывается - 54 ГБ в моей среде \ конфигурации.

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

обновление 2

Во время исследования проблемы, которую я сыгралс рядом опций \ конфигураций, которые не имели заметной разницы:

  • Режим принудительного GC сервера.
  • Настройка GC с малой задержкой.
  • Различные комбинации принудительного переключения GC напопробуйте амортизировать GC.
  • Min \ Max рабочие рабочие наборы.
2 голосов
/ 22 июня 2010

Похоже, вы не храните ссылку на большие данные. Сборщик мусора не будет собирать ссылочные объекты.

...