Виртуальная и физическая память / OutOfMemoryException - PullRequest
2 голосов
/ 13 января 2011

Я работаю над 64-битным приложением .Net Windows Service, которое по существу загружает кучу данных для обработки. Выполняя тестирование объема данных, мы смогли перегрузить процесс, и он выдал исключение OutOfMemoryException (у меня нет статистики производительности процесса, когда он завершился неудачей.) Мне трудно поверить, что процесс запросил кусок памяти, который бы превысил допустимое адресное пространство для процесса с момента его запуска на 64-разрядной машине. Я знаю, что этот процесс выполняется на машине, которая постоянно использует 80-90% физической памяти. У меня такой вопрос: может ли CLR генерировать исключение OutOfMemoryException, если на машине слишком мало доступной физической памяти, даже если процесс не превысит допустимый объем виртуальной памяти?

Спасибо за вашу помощь!

Ответы [ 3 ]

4 голосов
/ 13 января 2011

В 64-битной среде все еще существуют некоторые достижимые ограничения. Проверьте эту страницу для некоторых из наиболее распространенных. Короче говоря, да, вы все равно можете исчерпать память, если ваша программа загружает огромные 128 ГБ данных в виртуальную память. Вы также можете ограничить максимальный лимит в 2 ГБ на процесс, если у вас не установлена ​​переменная среды IMAGE_FILE_LARGE_ADDRESS_AWARE.

4 голосов
/ 13 января 2011

Другая возможность состоит в том, что программа пыталась выделить один блок памяти размером более 2 гигабайт, что является ограничением .NET. Это может произойти при добавлении объектов в коллекцию (чаще всего Dictionary или HashSet, но также List или любой другой коллекции, которая автоматически увеличивается.)

Dictionary и HashSet делают это часто, если вы пытаетесь положить в коллекцию более 47 миллионов предметов. Хотя коллекция может содержать около 89,5 миллионов, алгоритм, который увеличивает коллекцию, удваивает ее. Если вы начинаете с пустого Dictionary и начинаете добавлять предметы, коллекция удваивается несколько раз, пока не достигнет примерно 47 миллионов. Затем он снова пытается удвоиться и бросает OutOfMemoryException.

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

1 голос
/ 13 января 2011

Теоретически вы можете обратиться к этому адресу.

У вас есть физическая память, и когда вы превышаете, что вы начинаете использовать swap, который часто ограничен размером некоторых выбранных разделов диска.

Как правило, каждый имеет тенденцию иметь небольшое количество (например, один или два) кратных единиц физической памяти в качестве подкачки.

Так что да, вполне вероятно, что вы недоступны, в отличие отадресуемая память.

...