Ich muss eine große Liste von Strings erstellen und sie im Speicher behalten, aber beim Erstellen wird eine OutOfMemoryException ausgelöst. Laut Resource Monitor habe ich immer noch 1GB Speicher zur Verfügung. Ich fand diesen KB-Artikel , der das Problem anspricht, aber es scheint, als hätte es in Framework 1.1 SP1 behoben werden müssen (ich verwende 3,5 SP1).
Kann jemand etwas darüber erzählen, was hinter den Kulissen passiert? Beschränkt das .NET-Framework die Speicherkapazität eines einzelnen Prozesses (auf einem 32-Bit-System)? Wenn ja, kann ich sehen, warum, aber was nicht sinnvoll ist, ist, dass die Anwendung nur 1,6 GB verwendet und es noch ~ 1 GB für das System übrig ist.
Bearbeiten - Für diejenigen, die hier gefragt haben, gibt es weitere Informationen:
Ich habe eine Liste (Ja, ich könnte etwas anderes verwenden, aber ich entwickle gerade ein Prototyping.), ich erzeuge eine zufällige Zeichenfolge, indem ich eine Guid.NewGuid (). ToString () mache und sie in die Liste hole . Ich versuche, eine Liste mit so vielen Elementen zu erstellen, wie ich hineinpassen kann, und verschiedene Methoden zu testen, um nach einem bestimmten zu suchen. Meine erste Vermutung war, dass etwas Fragmentierung vor sich geht, aber ich habe alles außer dem unten stehenden Code fallen gelassen, und es passiert immer noch. Ich glaube nicht, dass dieser kleine Ausschnitt eine Menge Fragmentierung erzeugen könnte, aber ich liege wahrscheinlich falsch.
%Vor%Das Problem ist wahrscheinlich nicht, dass Sie nicht über den Speicher "verfügbar" verfügen, sondern eher, dass Sie den Speicher so stark fragmentiert haben, dass beim Versuch, ein Element zur Liste hinzuzufügen, und die Größe geändert werden muss. Kein einzelner verfügbarer Speicherblock kann es halten.
Dies wird auch zu OutOfMemoryException führen.
Wie groß ist die Liste, mit anderen Worten, wie viele Strings haben Sie genau oder grob, wenn Sie die Ausnahme erhalten?
Und wie bevölkern Sie die Liste? Kennen Sie die Anzahl der Artikel, die Sie hinzufügen möchten? Und wenn ja, geben Sie beim Erstellen der Liste die Kapazität an?
Wenn Sie nicht wissen, wäre es möglich, das herauszufinden, damit Sie diese Kapazität angeben können?
Der Standardkonstruktor von List & lt; T & gt; beginnt mit einem leeren Array als internen Speicher. Ein Aufruf von Add (T item) überprüft, ob eine Array-Größenänderung erforderlich ist, und verdoppelt die Kapazität (über die EnsureCapacity-Methode). Wenn die Capacity-Eigenschaft festgelegt ist ...
Angenommen, eine Kapazität von n würde bedeuten, dass Sie während der Größenänderung eine Gesamtspeicherauslastung von 3n haben.
Wie viele Elemente enthält Ihre Liste, wenn sie fehlschlägt? Verwenden Sie den Konstruktor, der eine Kapazität akzeptiert, wenn Sie wissen, wie viele Elemente hinzugefügt werden. Dadurch werden Größenänderungen vermieden, die möglicherweise durchgeführt werden müssen (und Ihre OutOfMemoryException kann direkt ausgelöst werden, wenn Sie große Speicherblöcke benötigen).
Vergessen Sie die Fragmentierung, LargeAddressAware oder gcAllowVeryLargeObjects ... Mein Problem mit dieser genauen Situation wurde gelöst, indem Sie das Kontrollkästchen "32-Bit bevorzugen" auf der Eigenschaftenseite meines Console-Projekts unter Build deaktivieren. Dies wurde standardmäßig eingestellt ... warum?
Ich kenne die Einzelheiten dieses Fehlers nicht wirklich, aber ich bin vor Jahren auf dieses oder etwas sehr ähnliches gestoßen. Wir haben festgestellt, dass die Anzahl der GDI-Handles, an die Ihre Bewerbung gebunden war, stark eingeschränkt war. Etwas wie 9.999. Wenn Sie dieses Limit erreichen, stürzt die Anwendung mit einer Ausnahme wegen zu wenig Speicher ab, unabhängig davon, wie viel Speicher frei ist.
Sie könnten also etwas Ähnliches tun, aber da Sie erwähnt haben, dass Sie mit Strings arbeiten, stelle ich mir vor, dass Sie den Heap zerstückeln und seine Kapazität überschreiten. Wenn Ihre Strings groß genug sind, befinden sie sich wahrscheinlich auf dem großen Objekt-Heap. Ich denke, dass die Implementierung für das LOH in der frühen Version des Frameworks sehr schlecht war. Wenn der Speicher mir richtig dient, wurden die Objekte nicht richtig freigegeben, was es sehr einfach macht, nur auf dem LOH Platz zu haben.
Siehe diese Links für weitere Informationen