Frage

Ich prüfe, wie groß eine Sammlung in .Net sein könnte. Technisch gesehen, könnte jede Sammlung Objekt wächst mit der Größe des physikalischen Speichers.

Dann testete ich den folgenden Code in einem Sever, die 16 GB Speicher, Windows 2003 Server ausgeführt wird und Visual Studio 2008. Getestet habe ich sowohl F # und C # -Code, und im Task-Manager sahen beim Laufen. Ich kann nach über die Erwachsen 2 GB Speicher, stürzte das Programm mit Out-of-memory Ausnahme, dass. Ich habe die Zielplattform x64 in der Eigenschaftenseite festgelegt.

open System.Collections.Generic

let d = new Dictionary<int, int>()

for i=1 to 1000000000 do
    d.Add(i,i)

Ich habe einen gleicher Test mit der C5 Sammlung Bibliothek. Das Ergebnis ist, dass das Wörterbuch in C5 könnte den gesamten Speicher aufbrauchen. Der Code verwendet C5:

let d = C5.HashDictionary<int, int> ()
for i=1 to 1000000000 do
    d.Add(i,i)

Wer weiß, warum?

War es hilfreich?

Lösung

Die Microsoft CLR hat eine 2 GB maximale Objektgröße zu begrenzen, auch die 64-Bit-Version. (Ich bin nicht sicher, ob diese Grenze bei anderen Implementierungen wie Mono auch vorhanden ist.)

Die Beschränkung gilt für jeden Single Objekt - nicht die Gesamtgröße aller Objekte -. Das bedeutet, dass es relativ einfach, mit einer Verbund Sammlung von irgendeiner Art umgehen

Es gibt eine Diskussion und einige Beispiel-Code hier ...

Es scheint sehr wenig offizielle Dokumentation zu sein, das zu dieser Grenze bezieht. Es ist schließlich nur eine Implementierung Detail des aktuellen CLR. Die einzige Erwähnung, dass ich bin mir dessen bewusst ist auf dieser Seite :

  

Wenn Sie einen 64-Bit laufen verwaltet   Anwendung auf einem 64-Bit-Windows   Betriebssystem, können Sie eine erstellen   Objekt von nicht mehr als 2 Gigabyte   (GB).

Andere Tipps

In Versionen von .NET vor 4.5 ist die maximale Objektgröße 2 GB. Von 4,5 ab können Sie größere Objekte zuzuweisen, wenn gcAllowVeryLargeObjects aktiviert ist. Beachten Sie, dass die Grenze für string nicht betroffen ist, sondern „Arrays“ sollte „Listen“ decken, da Listen von Arrays unterstützt werden.

Und klar zu sein, ein Wörterbuch verwendet ein einzelnes Array die Paare hinzuzufügen. Es wird (verdoppelt?) Gewachsen jedes Mal, es voll ist. Wenn es 512 Millionen Objekte sind, ist seine Größe 2GByte (mit einem 32-Bit-Objektzeiger und perfekte Verteilung vorausgesetzt). ein weiteres Element Hinzufügen macht das Wörterbuch erneut versuchen, die Array-Größe zu verdoppeln. Boom.

Die C5 HashDictionary verwenden lineares Hashing und wahrscheinlich verwenden eine Anordnung aus Schaufeln jeweils mehr (16?) Elemente. Es sollte später in das gleiche Problem (viel) läuft.

Die „erlauben große Objekte“ wird nur helfen, loszuwerden OOM Ausnahme zu erhalten.

Wenn man braucht speichern sehr viele Objekte das Problem, dass auf Sie werden sehen, GC Boxen (Pausen). Was wir getan haben, ist „versteckt“ von Daten aus GC, die in einge eine sehr praktische Lösung.

Siehe dazu: https://www.infoq.com/articles/ Big-Speicher-Teil-3

Sie können die Cache verwenden, die als Wörterbuch funktioniert: https://github.com/aumcode/nfx/tree/ Master / Quelle / NFX / ApplicationModel / Stapel

siehe den Abschnitt über caching

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top