2011-01-13 2 views
2

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

Благодарим за помощь!

+0

Он по-прежнему ограничен максимальным размером файла подкачки. Вы ударите его, прежде чем вы нажмете на адресную память. –

ответ

4

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

+0

+1. Хороший ответ, хорошая ссылка. – David

1

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

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

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

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

4

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

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

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

+0

предварительно выделите коллекцию, чтобы ее емкость была достаточно большой, чтобы удерживать сколько-нибудь предметов, которые вы ожидаете вставить в нее. Можете ли вы сказать, как я могу это сделать в случае HashSet, то есть preallocation? Я могу сделать это в списке , но как для HashSet? –

+0

@ Харис Хасан: Предварительное выделение 'HashSet' требует некоторого обмана. См. Http://blog.mischel.com/2008/05/21/more-on-net-collection-sizes/ –

+0

Спасибо, хорошая идея :) –

Смежные вопросы