Laden...

Dictionary wird Exception beim Einfügen vielen Datensätze

Erstellt von Christoph K. vor einem Jahr Letzter Beitrag vor einem Jahr 535 Views
Christoph K. Themenstarter:in
821 Beiträge seit 2009
vor einem Jahr
Dictionary wird Exception beim Einfügen vielen Datensätze

Hallo,

ich habe folgenden Code zum Befüllen eines Dictionarys.
Wenn das 95991738 Element eingefügt wird, die Exception "Die Arraydimensionen haben den unterstützten Bereich überschritten." geworfen.
Kann sich das jemand erklären?


            var test = new Dictionary<int, int>();

            var count = 0;
            while (true)
            {
                test.Add(count++, 1);
            }

A
764 Beiträge seit 2007
vor einem Jahr

Sieht für mich nach einer OutOfMemoryException aus.

Christoph K. Themenstarter:in
821 Beiträge seit 2009
vor einem Jahr

Warum sollte die auftreten?
Es ist eine 64 Bit Applikation und auf dem Computer ist noch genügend freien RAM vorhanden.

D
261 Beiträge seit 2015
vor einem Jahr

Verwendest du .NET Framework? Maximale Objektgröße ist dort standardmäßig (auch in 64 Bit) 2 GB

Versuch mal in der app.config:


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

A
764 Beiträge seit 2007
vor einem Jahr

Ich habe kurz nachgelesen. ~Der Heap bei 32-Bit-Applikationen scheint eine maximale Größe von 1,5 GB zu haben. Das würde zu den 95991738 Elementen passen.

Aber ehrlich gesagt, weiß ich es nicht. Vielleicht kann einer von unseren Profis hier die Frage beantworten.

[Edit]
Ich habe es mal ausprobiert, wenn ich die App auf x86 stelle, kommt die Exception nach 23997908 Elementen. Mit x64 bei 95991738 Elementen.

6.911 Beiträge seit 2009
vor einem Jahr

Hallo Christoph K. ,

die Exception "Die Arraydimensionen haben den unterstützten Bereich überschritten."

Die Exception hat auch einen Typ. Schau dir den an, so weißt du worum es geht.
Also ob es OutOfMemory, IndexOutOfRange, etc. ist. Der Text alleine ist schön, aber für eine Diagnose ist der Typ wichtiger.

auf dem Computer ist noch genügend freien RAM vorhanden.

Bei der OutOfMemoryException geht es v.a. darum ob der GC einen zusammenhängenden Speicherbereich verwenden / finden / vom OS verlangen kann, der groß genug ist um das Objekt (hier beim Dictionary ein internen Array) halten zu können. Ist das nicht der Fall -> OOM.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

16.806 Beiträge seit 2008
vor einem Jahr

Bei der OutOfMemoryException geht es v.a. darum ob der GC einen zusammenhängenden Speicherbereich verwenden[...]

.. oder das System nicht mehr genug Handles zur Verfügung hat.
Man sollte daher schon wissen, was OutOfMemoryException einfach bedeutet: weit mehr als nur "out of memory".

Und noch besser isses natürlich potentiellen Helfern einfach zu sagen, welche Exception geworfen wird.
Dann muss niemand raten, weil Glaskugeln haben wir leider noch nicht.
[Hinweis] Wie poste ich richtig? 5. Problem genau beschreiben - inkl. genauer Fehlermeldung

Liegt aber nahe, dass es sich um eine OutOfMemoryException handelt.
Bestätigt das bitte.

T
2.219 Beiträge seit 2008
vor einem Jahr

Meine Frage wäre auch welchen Sinn dieser Code hat.
Du hast hier eine while(true) Schleife was so oder so zu einem endlosen Durchlauf führt und früher oder später zu einem Überlauf oder OutOfMemory Exception.
Etwas mehr Context zu deinem Vorhanden könnte ggf. auch zu einer sinnvolleren Lösung führen.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

Christoph K. Themenstarter:in
821 Beiträge seit 2009
vor einem Jahr

Es handelt sich um eine OutOfMemoryException

@T-Virus: Es handelt sich um die Abstraktion eines realen Problems. Es geht im Endeffekt darum, das ein RAM-Cache benötigt wird, der entsprechend viele Objekte in einem Dictionary beinhalten soll.

T
2.219 Beiträge seit 2008
vor einem Jahr

@Christoph K.
Welches reale Problem wäre dies den, wenn ich fragen darf.
Sieht dein Code im produktiv System genauso aus, dann kann es nicht funktionieren.
Wäre es hier nicht sinnvoll nur benötigte Daten direkt im Cache abzulegen anstatt Unmengen an Einträgen zu generieren?
Dies wäre für sich gegeben schon ein Dictionary mit eindeutigen Keys.

Einträge sollten nur abgelegt/eingefügt werden, wenn diese benötigt werden sonst läufst du eben auf das Speicherproblem.
Ggf. wäre auch die Einbindung von Redis als Cacheserver sinnvoll um nahezu endlose Daten zu speichern.
Nutzen wir auch um größere verteilte Caches zu nutzen.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

6.911 Beiträge seit 2009
vor einem Jahr

Hallo Christoph K. ,

ein RAM-Cache benötigt wird, der entsprechend viele Objekte in einem Dictionary beinhalten soll.

Ist Cache in-memory ein Möglichkeit?
Das wären .NET-Bordmittel und genau für solche Szenarien getrimmt.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

T
2.219 Beiträge seit 2008
vor einem Jahr

Zusätzlich dazu, kannst du auch Redis einbinden.
Wenn du nur einen Prozess hast, kannst du die Daten einfach lokal vorhalten und in Redis speichern/updaten.
Damit könntest du nahe zu endlose Datenmengen wegspeichern.
Durch Pub/Sub kannst du dann auch bei verteilten Anwendungen die Caches updaten lassen.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.