2016-05-30 3 views
0

ich auf diesem Befehl bin immerFehler bei der Definition Zahl ist größer als 89.478.457

Dictionary<UInt64, int> myIntDict = new Dictionary<UInt64, int>(89478458); 

diesen Fehler:

System.OutOfMemoryException was unhandled HResult=-2147024882 
Message=Array dimensions exceeded supported range. 
Source=mscorlib 
StackTrace: 
    at System.Collections.Generic.Dictionary`2.Initialize(Int32 capacity) 
    at System.Collections.Generic.Dictionary`2..ctor(Int32 capacity, IEqualityComparer`1 comparer) 

Auf 89.478.457 gibt es keine Fehler. Hier ist die Quelle der Initialisierung in Dictionary.cs:

private void Initialize(int capacity) 
    { 
     int size = HashHelpers.GetPrime(capacity); 
     ... 
     entries = new Entry[size]; 
     ... 
    } 

Wenn ich dies zu reproduzieren, passiert der Fehler auf der Array-Erstellung. Eintrag ist eine Struktur in diesem Fall mit der Größe 24. Wenn wir max Int32 (0x80000000-1) bekommen und dividieren auf 24 = 89478485 und diese Zahl ist zwischen den Primzahlen 89478457 und 89478503.

Bedeutet dies, dass Array von struct kann nicht größer sein als maxInt32/sizeOfThisStruct?

BEARBEITEN:

Ja. Ich gehe tatsächlich über 2 GB. Dies passiert, wenn das Dictionary das interne Array von struct Entry erstellt, wo die Paare (Schlüssel, Wert) gespeichert sind. In meinem Fall ist die Größe von (Entry) 24 Bytes und als Werttyp ist inline zugeordnet.

Und die Lösung ist die gcAllowVeryLargeObjects Flagge (danke Evk). Eigentlich in .net Kern ist die Flagge the environment variable COMPLUS_gcAllowVeryLargeObjects (danke svick).

Und ja, Paparazzi ist richtig. Ich muss darüber nachdenken, wie ich meine Erinnerung nicht verschwenden soll. Danke euch allen.

+0

Ich frage mich, warum Sie dictionary müssen, dass in der Größe groß?Die wirkliche Praktikabilität dieser Tortur ist, was ich in Frage stelle –

+0

@BenPhilipp Int ist nur für den Test. Eigentlich ist eine Struktur. – Mottor

+0

@MukeshAdhvaryu Was verwenden Sie für spärliche 3D-Array. – Mottor

Antwort

7

Es gibt eine bekannte Einschränkung der .NET-Laufzeitumgebung - die maximal erlaubte Objektgröße auf dem Heap beträgt 2 GB, selbst bei einer 64-Bit-Version der Laufzeit. Aber ab .NET 4.5 gibt es configuration option, mit dem Sie dieses Limit (nur bei der 64-Bit-Version von Runtime) noch lockern und größere Arrays erstellen können. Beispiel für die Konfiguration, das zu ermöglichen, ist:

<configuration> 
    <runtime> 
    <gcAllowVeryLargeObjects enabled="true" /> 
    </runtime> 
</configuration> 
+1

Funktioniert das Gleiche für .Net Core? Ich denke, .Net Core verwendet nicht app.config. – svick

+3

Siehe auch [diese Antwort] (http://stackoverflow.com/a/37423015/41071). – svick

+0

Danke für Informationen. Scheint, dass dein Link deine Frage beantwortet. Ich habe getestet und ohne diese Option Verhalten scheint das gleiche (so wirft es auch OutOfMemoryException beim Zuweisen von zu großen Array). – Evk

0

Auf der Oberfläche Wörterbuch keinen Sinn macht
Sie nur int eindeutige Werte
Sie wirklich haben, können Sie haben, dass meine Duplikate

UnInt32 bis 4.294.967.295 geht
Warum verschwenden Sie 4 Bytes?

89.478.458 Zeilen Derzeit eine Reihe 12 Bytes
Sie haben 1 GB bei etwa 83.333.333 Zeilen
Da ein Objekt wirklich eine Strebe zusammenhängenden Speicher 1 GB mehr eine praktische Grenze ist

Wenn Werte braucht, ist 24
Dann 1 gb in 31.250.000

dass

Sie mehr als ein collectio ist gespalten kann in nur eine wirklich große Sammlung n

Oder eine Klasse verwenden, da dann ist es nur eine Referenz mit meiner Meinung nach 4 Byte

+0

In der UInt64 ist Position in 3D-Array (X, Y, Z) codiert, der Wert ist der Wert im Array. Sie werden dynamisch vom Benutzer (SQL) gefüllt und das Array ist spärlich. Dann gibt es viele Berechnungen. – Mottor

+0

Dann schlage ich eine effizientere Codierung vor, da Sie viel Platz verschwenden. – Paparazzi

+0

Es ist mit Bitmaske codiert. In der Realität liegt die normale Größe zwischen 100000 und 500000, aber ich sollte wissen, wo das Limit ist, weil ich nichts über die Daten zur Kompilierzeit weiß. – Mottor