Hashtable - недостаточно памяти - PullRequest
4 голосов
/ 12 января 2010

Я использую Hashtable в своем приложении c #. Я загружаю миллионы ключей, но после того, как приложение превысило 3,7 ГБ ОЗУ, оно выдает исключение «недостаточно памяти».

Я использую операционную систему x64, и компьютер имеет 16 ГБ оперативной памяти. Я думал о том, может быть, это ограничение x86. Я изменил тип сборки на x64, но все равно получаю ошибку.

Есть ли максимальный объем памяти для объекта в .net? Можно ли что-то сделать, чтобы использовать всю память?

Спасибо, Andrew

Ответы [ 5 ]

8 голосов
/ 12 января 2010

Посмотрите на этот предыдущий ответ: .NET Max Memory Используйте 2 ГБ даже для сборок x64

Ограничение 2 ГБ применяется к каждому объекту в отдельности. Общий объем памяти, используемый для всех объектов, может превышать 2 ГБ.

6 голосов
/ 12 января 2010

Используйте Dictionary<,> вместо HashTable. В HashTable ключ и значение являются объектами, поэтому, если они являются типами значений, они будут помещены в квадрат. Dictionary может иметь типы значений в качестве ключа и / или значения, которое использует меньше памяти. Например, если вы используете int в качестве ключа, каждый из них будет использовать 28 байтов в HashTable, в то время как они используют только 4 байта в Dictionary.

Если ключ и значение являются типами значений и используют менее 8 байтов, Dictionary сможет содержать больше элементов, чем HashTable.

1 голос
/ 09 мая 2012

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

Я попробовал идею "Guffa" об использовании словаря на небольшом примере хеш-таблицы, и результирующий словарь фактически увеличился в размере!

Его предложение заставило меня задуматься о том, что я на самом деле писал в Hashtable. Поэтому я посмотрел на эту страницу и решил, что мне действительно не нужно хранить данные типа Long , Integer более чем достаточно. Я знаю, что я, вероятно, рассказываю всем вам, гуру, о том, что является ослепительно очевидным, но мне удалось уменьшить результирующие сериализованные хаст-таблицы (всего их 12) с 81,9 МБ до 69,4 МБ, просто объявив переменные как целые числа вместо Longs.

Это на самом деле не решило мою проблему, но, безусловно, уменьшит время, необходимое для их загрузки обратно в память.

1 голос
/ 12 января 2010

В этой статье говорится, что .NET ограничивает размер одного объекта двумя гигабайтами.

0 голосов
/ 23 ноября 2017

Эта проблема не имеет никакого отношения к объему физической памяти в вашей системе, а также к тому, скомпилирована ли x64 или нет. Также не верно, что .NET должен ограничивать объекты до 2 ГБ. (Возможно, вы захотите изучить кучу больших объектов в .NET 4.5 для получения дополнительной информации об этом.) Причина, по которой вы получаете «Недостаточно памяти», заключается в том, что процесс не может отобразить непрерывный раздел памяти в запрошенном вами размере. *

Эрик Липперт имеет отличную статью в блоге на эту тему, и я заметил, что он прокомментировал этот вопрос, но, к сожалению, не ответил на него.

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

У меня была такая же проблема, и мне пришлось использовать тот же подход. Работа с неровными массивами может помочь, или разбить ваши данные на несколько логических компонентов и создать серию меньших HashTables.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...