Es gibt ein Limit von 2 GB pro Objekt, aber denken Sie daran, dass ein Referenztyp nur die Zeigergröße (8 Bytes für x64) verwendet, wenn es ein Feld in einer Klasse ist.
Array Speichergrößen werden wie folgt berechnet (fixed-Overhead zu ignorieren):
Für Arrays von Strukturtypen:
- Array Speichergrße = #elements im Array * Größe jedes Elements
Für Arrays von Referenztypen:
- Array Speicher size = # Elemente im Array * Referenzgröße (4 Bytes für x8x, 8 Bytes für x64)
Ein HashSet könnte also Objekte referenzieren, die mehr als die 2GB Grenze umfassen. Wenn Sie die Größe für jedes Feld in der Klasse addieren - 64 Bit für Referenztypen und die volle Größe für Strukturtypen - muss es weniger als 2 GB betragen.
Sie könnten eine Klasse haben, die zum Beispiel 16x1GB Arrays von Bytes enthält.
Beachten Sie auch, dass es möglich ist, eine Anwendung so zu konfigurieren, dass Arrays mit einer Größe von mehr als 2 GB zulässig sind. Die maximale Anzahl von Elementen in einem eindimensionalen Array kann 2G (2 * 1024 * 1024 * 1024) jedoch nicht überschreiten.
Ich vermute, dass die Objekte, die Sie in der HashSet speichern, Referenztypen sind, so dass es nur 64 Bits für jede im internen HashSet-Array verwendet, während die volle Größe jedes Ihrer Objekte viel größer als 64 Bit ist - Das ergibt eine Gesamtgröße von mehr als 2 GB.
am referencesource für HashSet Blick zeigt, dass die folgenden Felder verwendet:
private int[] m_buckets;
private Slot[] m_slots;
Wo Slot
wie so definiert:
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
}
Es ist wie jeder nimmt Slot
Struktur aussieht 16 Bytes auf x64 Wenn T
ein Referenztyp ist, bedeutet dies, dass HashSet OutOfMemory auslöst, wenn die Anzahl der verwendeten Slots 2GB/16 = 128M Elemente
0 überschreitet
(Wenn T
eine Struktur ist, wird der Speicher je nach Größe viel schneller verbraucht.)
Duplizieren? http: // Stapelüberlauf.com/a/1088044/993547 –
Die Beschränkung von 2 GB gilt für einzelne Objekte und wirkt sich auf die maximale Größe von Arrays als Beispiel aus. Wenn jedoch die in einem Hash-Set gespeicherten 'T's Klassen sind, dann wird nur eine 32- oder 64-Bit-Referenz im Hash-Set gespeichert, die tatsächliche Objektinstanz und ihre Größe sind im Zusammenhang mit der Hashset. OutOfMemory im Allgemeinen bedeutet, dass .NET wirklich nicht genügend Arbeitsspeicher zur Verfügung hat, es sollte niemals bedeuten, dass irgendein beliebiges Objekt entschieden hat, dass dies so hoch wie möglich ist. –
Das Limit von 2 GB ist nicht mehr so einfach; Es gibt eine 'gcAllowVeryLargeObjects'-Option - aber der' int.MaxValue'-Grenzwert gilt auch dann, wenn das aktiviert ist. im Falle von 'T' =' string' könnten Sie vielleicht ein bisschen größer werden, wenn ** ** HashSet 'durch große Arrays begrenzt ist! nicht trivial –