Страницы

Поиск по вопросам

четверг, 10 января 2019 г.

System.OutOfMemoryException при добавлении элемента в словарь

Возникла проблема с ограничениями памяти для приложения. Из того что я понял: для приложения или под созданный объект (в моем случае это словарь) выделяется не больше 2Гб памяти. Хотелось бы создать словарь, который мог бы быть размера как минимум свободной части оперативной памяти. Как это сделать?
StackTrace исключения:
в System.Collections.Generic.Dictionary`2.Resize(Int32 newSize, Boolean forceNewHashCodes) в System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) в System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)


Ответ

Сперва об OutOfMemoryException. Вопреки расхожему мнению, это исключение не означает, что закончилась память. Оно означает, что отсутствует требуемый непрерывный объем памяти. При этом свободной памяти еще может быть много, просто она фрагментирована. Например, CLR хочет выделить участок в 100 Мб, но есть только 20 свободных участков по 50 Мб. Свободная память есть, при этом OutOfMemoryException тоже есть.
Со словарем проблема заключается в том, что для изменении его размера требуется, грубо говоря, в два раза больше памяти, чем он занимает. Т.е. если на данный момент ваш словарь полностью заполнен и занимает 100 Мб (сам объект словаря, ключи/значения при этом могут храниться отдельно), то при добавлении очередного элемента нужно увеличить размер словаря, и на это требуется выделить 200 Мб памяти.
Теперь про ограничения. 2 Гб -- это объем памяти, выделяемый для 32-битного приложения (2^32). Для того, чтобы получить возможность кушать больше памяти (2^64), приложение должно быть 64-битным. При этом необходимо также включить опцию , которая позволит иметь массивы объемом больше 2 Гб.
Также вам стоит посмотреть внимательнее на ваш алгоритм, возможно его можно пересмотреть в сторону уменьшения потребления памяти.
Резюмируя в порядке важности:
Пересмотрите алгоритм (можете выложить его здесь отдельным вопросом и вам постараются подсказать). Сделайте приложение 64-битным и включить опцию

Комментариев нет:

Отправить комментарий