Force garbage collection von arrays, C#
Ich habe ein problem, wo ein paar 3-dimensionale arrays weisen Sie eine riesige Menge an Speicher und das Programm braucht manchmal ersetzen Sie Sie mit größere/kleinere und wirft eine OutOfMemoryException.
Beispiel: es gibt 5 zugeteilt 96 MB-arrays (200x200x200, 12 Daten-bytes je Eintrag) und das Programm braucht, um Sie zu ersetzen mit 210x210x210 (111MB). Es tut es in einer Weise, die ähnlich zu dieser:
array1 = new Vector3[210,210,210];
Wo array1-array5 sind die gleichen Felder, die zuvor verwendet. Diese sollten die alten arrays als Kandidaten für die garbage-collection aber scheinbar die GC nicht handeln schnell genug, und lässt die alten arrays zugewiesen werden, bevor die Zuteilung der neuen - die Ursachen der OOM - während, wenn Sie befreit werden, bevor die neuen Zuordnungen der Raum sollte genug sein.
Was ich Suche, ist eine Möglichkeit, so etwas zu tun:
GC.Collect(array1) //this would set the reference to null and free the memory
array1 = new Vector3[210,210,210];
Ich bin mir nicht sicher, ob eine vollständige garbage collecion eine gute Idee wäre, da dieser code kann (in einigen Situationen) ausgeführt werden müssen, ziemlich oft.
Gibt es eine richtige Weg, dies zu tun?
InformationsquelleAutor der Frage John Doe | 2009-07-09
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dies ist nicht eine genaue Antwort auf die ursprüngliche Frage, "how to force GC', doch ich denke, es wird Ihnen helfen zu überdenken, Ihr Problem.
Nachdem ich Ihr Kommentar,
Werde ich den Verdacht, dass Sie möglicherweise haben Fragmentierung des Speichers. Wenn das Objekt groß ist (85000 bytes unter .net 2.0 CLR, wenn ich mich richtig erinnere, ich weiß nicht ob es geändert wurde oder nicht), wird das Objekt zugewiesen werden, in einem speziellen heap, Large Object Heap (LOH). GC hat wieder den Speicher von nicht erreichbaren Objekte in LOH, noch, Sie nicht durchführen Verdichtung, in LOH, als auch auf die anderen Haufen (gen0, gen1 und gen2), wegen der Leistung.
Wenn Sie Häufig allocate und deallocate große Objekte, es wird LOH fragmentiert, und auch wenn man mehr freien Speicher insgesamt als das, was Sie benötigen, können Sie nicht haben, ein zusammenhängender Speicherbereich mehr, daher bekommen OutOfMemory-exception.
Ich denken kann, zwei Möglichkeiten in diesem moment.
InformationsquelleAutor der Antwort Chansik Im
Scheint Sie schon in LOH (Large object heap) Fragmentierung Problem.
Large Object Heap
CLR Inside Out Large Object Heap Uncovered
Können Sie überprüfen, um zu sehen, wenn Sie loh Fragmentierung Probleme mit SOS
Überprüfen Sie diese Frage für ein Beispiel dafür, wie SOS-prüfen des loh.
InformationsquelleAutor der Antwort Pop Catalin
Zwingen, eine Garbage Collection ist nicht immer eine gute Idee (es kann tatsächlich fördern die Lebensdauer der Objekte in einigen Situationen). Wenn Sie müssen, verwenden Sie:
InformationsquelleAutor der Antwort Mitch Wheat
Ist das nicht nur large object heap-Fragmentierung? Objekte > 85.000 bytes reserviert werden, auf dem large object heap. Der GC schafft Platz in diesem Haufen, aber nie komprimiert die verbleibenden Objekte. Dies kann dazu führen, Unzureichende zusammenhängenden Speicher erfolgreich reserviert einen großen Objekt.
Alan.
InformationsquelleAutor der Antwort
Wenn ich spekulieren Sie problem ist nicht wirklich, dass Sie sich von Vector3[200,200,200], um ein Vector3[210,210,210] aber, dass die meisten wahrscheinlich, Sie haben ähnlich wie die vorherigen Schritte, bevor Sie diese:
Wenn das wahr ist, würde ich vorschlagen, eine bessere Strategie. Versuchen Sie über die Zuteilung, vielleicht verdoppeln Sie die Größe jedes mal anders als immer die Zuweisung nur der Raum, den Sie brauchen. Vor allem, wenn diese arrays sind immer von Objekten verwendet, müssen pin den Puffer (D. H., wenn, die haben verbindungen zu native code)
So, statt der oben genannten, haben so etwas wie dieses:
InformationsquelleAutor der Antwort Mike Dinescu
Sie vielleicht nicht immer erfasst, weil Sie sind, auf das verwiesen wird irgendwo, wo man Sie nicht erwartet.
Als test versuchen Sie, Ihre Referenzen zu WeakReferences statt und sehen, ob das löst Ihre OOM problem. Wenn es nicht dann Sie verweisen, Sie woanders.
InformationsquelleAutor der Antwort Joseph
Ich verstehe, was Sie versuchen zu tun, und drängen auf sofortige garbage-collection ist wahrscheinlich nicht der richtige Ansatz (da die GC ist subtil in seiner Weise und schnell zum Zorn).
Sagte, dass, wenn Sie wollen , Funktionalität, warum nicht?
InformationsquelleAutor der Antwort plinth
Einer OutOfMemory-Ausnahme intern löst einen GC-Zyklus automatisch nach und versucht, die Zuordnung wieder vor dem eigentlich auslösen der Ausnahme dem code. Der einzige Weg, Sie könnten mit OutOfMemory-exceptions ist, wenn Sie halten, Verweise auf zu viel Speicher. Klar, die Verweise so schnell wie Sie können, indem Sie Sie null.
InformationsquelleAutor der Antwort clemahieu
Teil des Problems kann sein, dass Sie die Zuteilung eines mehrdimensionalen Arrays, das dargestellt ist als ein einzelner zusammenhängender block im Speicher auf dem large object heap (mehr details hier). Dieser block kann andere Zuwendungen, da gibt es nicht einen zusammenhängenden freien block zu verwenden, auch wenn es noch einige freie Platz irgendwo, daher der OOM.
Versuchen, die Zuweisung es wie ein jagged array - Vector3[210][210][210] - die spreads der arrays um das Gedächtnis nicht als ein einziger block, und sehen, ob das verbessert die Angelegenheiten
InformationsquelleAutor der Antwort thecoop
John, Erstellen von Objekten > 85000 Byte wird das Objekt am Ende in der large object heap. Der large object heap ist nie verdichtet, stattdessen wird der freie Speicherplatz wird wieder verwendet.
Dies bedeutet, dass, wenn Sie durch die Zuweisung größerer arrays jedes mal, können Sie am Ende in Situationen, in denen LOH ist zersplittert, daher der OOM.
können Sie überprüfen, ob dies der Fall ist, indem wir den debugger an der Stelle der OOM und immer einen dump Absenden dieses dump auf MS durch ein connect-bug (http://connect.microsoft.com) wäre ein guter Anfang.
Was ich versichern kann ist, dass der GC das richtige zu tun versuchen, Sie zu befriedigen, Zuordnung Anfrage, dieses beinhaltet zum Auftakt ein GC zu reinigen, den alten Müll zu befriedigen, die neue Aufteilung bei Anfragen.
Ich weiß nicht, was die Politik und teilen von Speicherabbildern auf Stackoverflow, aber ich würde glücklich sein, zu schauen, zu verstehen, Ihre problem mehr.
InformationsquelleAutor der Antwort mfawzymkh