5 Stimmen

C#: Wird GC sammeln, wenn es Speicher benötigt, oder wird es out of memory Ausnahme geben?

Ich habe eine Schleife in meinem Code, die viele byte[] Arrays (ca. 1 bis 2 MB jeder) generiert, füllt sie mit Daten, und dann verwerfen Sie den Verweis. Auch wenn der Verweis nur für kurze Zeit gehalten wird gehalten wird, kann ich sehen, wie die private Arbeitsmenge wächst.

Nun, wenn ich versuche, ein großes Array (~ 400 MB) nach der Schleife zuzuweisen, könnte ich eine Out of Memory-Ausnahme erhalten? Oder wird die Zuweisung die GC zwingen, die transienten Daten zu sammeln?

Danke!

2voto

CodesInChaos Punkte 103089

Viele 1-2MB große Arrays zu erzeugen ist eine schlechte Idee. Selbst wenn Sie vermeiden, dass der Speicher knapp wird, leidet die Leistung darunter. Die Zuweisung vieler kurzlebiger Objekte auf dem großen Objekt-Heap ist ein Zuweisungsmuster, mit dem der aktuelle GC nicht gut umgehen kann.

Ich empfehle dringend, sie wann immer möglich wiederzuverwenden. Implementieren Sie einen Pool, in den Sie die Arrays werfen, sobald Sie sie nicht mehr benötigen. Und dann prüfen Sie bei der Zuweisung zuerst, ob Sie die Anforderung aus dem Pool erfüllen können. Dieses Muster hat in einem meiner Programme zu enormen Leistungsvorteilen geführt.

Ich denke, voller Speicher erzwingt eine GC, aber wenn nicht verwaltete Zuweisungen um die gleiche Zeit passieren, können Sie noch OOMs erhalten.

1voto

Archimagus Punkte 11

Wenn Sie darüber besorgt sind, können Sie immer GC.Collect(); vor dem großen Array nach der Schleife aufrufen, das wird eine Garbage Collection aller Generationen erzwingen. Tun Sie dies jedoch nicht in der Schleife, es sei denn, Sie sind nicht besorgt über die Zeit, da dies ziemlich langsam sein kann (zu langsam für eine Schleife, nicht so sehr für eine einmalige Sache).

0voto

Mr47 Punkte 2626

Das kommt ganz darauf an. Sie können nicht sicher sein, dass der Garbage Collector rechtzeitig verwirft. Bei Byte-Arrays sind Sie einigermaßen sicher, aber die meisten Objekte werden zu spät verworfen, wenn Sie sie stark nutzen, ohne die dispose() Methode.
Dies führt zu Out-of-Memory-Ausnahmen, auch wenn Sie möglicherweise alle Verweise verworfen haben.
Wenn Sie Probleme haben, können Sie versuchen GC.Collect(0); obwohl dies in der Regel nicht ratsam ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X