Существует ограничение на 2 ГБ на объект, но помните, что ссылочный тип использует только размер указателя (8 байтов для x64), когда это поле в классе.
размеров матрицы памяти вычисляются следующим образом (без учета фиксированных накладных расходов):
Для массивов типов структуры: размер памяти
- Array = #elements в массиве * размер каждого элемента
Для массивов ссылочных типов:
- массива памяти size = # elementments в массиве * размер ссылки (4 байта для x8x, 8 байтов для x64)
Так что HashSet может ссылаться на объекты на сумму намного больше, чем ограничение 2 ГБ. Просто добавьте размер каждого поля в классе - 64 бита для ссылочных типов и полный размер для типов struct - он должен быть меньше 2 ГБ.
Например, у вас может быть класс, содержащий 16x1GB массивы байтов.
Также обратите внимание, что можно настроить приложение, чтобы разрешить массивы размером более 2 ГБ, хотя максимальное количество элементов в одномерном массиве по-прежнему не может превышать 2G (2 * 1024 * 1024 * 1024).
Я подозреваю, что объекты, которые вы храните в HashSet, являются ссылочными типами, поэтому для каждого из них во внутреннем массиве HashSet используется только 64 бита, а полный размер каждого из них намного больше, чем 64 бит - который дает общий размер, превышающий 2 ГБ.
Глядя на referencesource для HashSet показывает, что используются следующие массивы:
private int[] m_buckets;
private Slot[] m_slots;
Где Slot
определяется следующим образом:
internal struct Slot {
internal int hashCode; // Lower 31 bits of hash code, -1 if unused
internal T value;
internal int next; // Index of next entry, -1 if last
}
Похоже, каждый Slot
структуры занимает 16 байт на 64 когда T
является ссылочным типом, что означает, что HashSet будет вызывать OutOfMemory, когда количество используемых слотов превышает 2GB/16 = 128M элементов
(Если T
- это структура, то в зависимости от его размера у вас скоро будет нехватка памяти.)
Duplicate? Http: // StackOverflow.com/a/1088044/993547 –
Ограничение 2GB для отдельных объектов и в качестве примера будет влиять на максимальный размер массивов. Однако, если 'T', которые вы сохранили в hashset, являются классами, тогда в хешсет сохраняется только 32- или 64-разрядная ссылка, фактический экземпляр объекта и его размер не будут иметь значения в контексте HashSet. OutOfMemory в целом означает, что в .NET действительно закончилась нехватка памяти, это никогда не должно означать, что какой-то произвольный объект решил, что это настолько высоко, насколько это возможно. –
Ограничение на 2 ГБ не так просто; существует опция 'gcAllowVeryLargeObjects', но предел' int.MaxValue' по-прежнему применяется, даже если это включено; в случае 'T' =' string', вы можете получить немного больше, хотя - ** если ** 'HashSet' ограничен большими массивами! не является тривиальным –