Почему Был бы Из Исключения Памяти быть Брошенным, если Память Доступна?

У меня есть довольно простое приложение C#, которое имеет, создает большую хеш-таблицу. Ключи этой хеш-таблицы являются строками, и значения являются ints.

Прогоны программы, прекрасные приблизительно до 10,3 миллионов объектов, добавляются к хеш-таблице, когда из ошибки памяти брошен на строку, которая добавляет объект к hasbtable.

Согласно диспетчеру задач, моя программа только использует 797 МБ памяти, и существует все еще доступные более чем 2 ГБ. Это - 32-разрядная машина, таким образом, я знаю, что только в общей сложности 2 ГБ могут использоваться одним процессом, но это все еще оставляет приблизительно 1.2 ГБ, в которых хеш-таблица должна смочь расшириться.

Почему был бы из ошибки памяти быть брошенным?

9
задан John Saunders 27 June 2010 в 14:43
поделиться

6 ответов

Теоретически вы получаете 2 ГБ для процесса, но на самом деле это 2 ГБ непрерывной памяти, поэтому, если память вашего процесса фрагментирована, вы получите меньше этого.

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

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

В качестве альтернативы, если не критично, что он находится в памяти, какое-то решение для базы данных может быть лучше и даст вам больше гибкости, если оно достигнет точки, когда оно не поместится в памяти.

11
ответ дан 4 December 2019 в 10:30
поделиться

Используйте Process Explorer (www.sysinternals.com) и посмотрите на виртуальное адресное пространство вашего процесса. В отличие от «частных байтов» (которые представляют собой объем памяти, занятой процессом), виртуальное адресное пространство показывает самый высокий используемый адрес памяти. Если фрагментация высока, она будет намного больше, чем «Частные байты».

Если вашему приложению действительно требуется столько памяти:

  • Рассмотрите возможность перехода на 64-разрядную версию
  • Включите флаг / LARGEADDRESSAWARE, который предоставит вашему 32-разрядному процессу 4 ГБ ОЗУ в 64-разрядной операционной системе, и 3 ГБ, если 32-разрядная Windows загружается с флагом / 3 ГБ.
3
ответ дан 4 December 2019 в 10:30
поделиться

Вы должны использовать что-то вроде hibrid между массив и связанный список. Поскольку связанный список занимает больше памяти на элемент, чем массив, но массиву требуется непрерывное пространство памяти.

0
ответ дан 4 December 2019 в 10:30
поделиться

Вероятно, это связано с фрагментацией памяти: у вас еще есть свободная память, но не непрерывная. Память разделена на страниц , обычно размером 4 КБ, поэтому, если вы выделяете 4 МБ, вам потребуется 1024 непрерывных страницы памяти в адресном пространстве вашего процесса (они не должны быть физически непрерывны, поскольку память виртуализирована для каждого процесса).

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

4
ответ дан 4 December 2019 в 10:30
поделиться

Программа, которую вы запускаете, имеет ограниченные ресурсы из-за того, что отладчик Visual Studio пытается отслеживать все, что вы делаете в своем приложении (точки останова, ссылки, стек и т. д.).

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

    +-------+
    | large |       collected less often (~1/10+ cycles)
  +-+-------+-+              |
  |   medium  |              |
+-+-----------+-+            V
|     small     |   collected more often (~1/3 cycles)
+---------------+

ПРИМЕЧАНИЕ: числа взяты из памяти, так что относитесь к ним с недоверием.

1
ответ дан 4 December 2019 в 10:30
поделиться

Вы просто смотрите не в том столбце. Взгляните на столбец «Размер фиксации», он должен быть около 2 ГБ.

http://windows.microsoft.com/en-us/windows-vista/What-do-the-Task-Manager-memory-columns-mean

1
ответ дан 4 December 2019 в 10:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: