Sie auf diese Methode richtig funktioniert verlassen können, diese Ausnahme ist sehr wahrscheinlich in einem 32-Bit-Prozess auszulösen, wenn Sie nach 250 Megabyte fragen. Das wird schwierig zu bekommen sein, wenn das Programm eine Weile läuft.
Ein Programm nie stürzt mit OOM ab, weil Sie den gesamten verfügbaren virtuellen Speicheradressraum verbraucht haben. Es stürzt ab, weil im Adressraum kein Loch mehr vorhanden ist, das groß genug für die Zuweisung ist. Ihr Code fordert ein Loch an, das groß genug ist, um 250 Megabyte in einem Zug zuzuordnen. Wenn Sie die Ausnahme nicht erhalten, können Sie sicher sein, dass diese Zuweisung nicht fehlschlägt.
Aber 250 Megabyte ist ziemlich viel, das ist ein wirklich großes Array. Und es ist sehr wahrscheinlich, dass es aufgrund eines Problems, das "Adressraumfragmentierung" genannt wird, fehlschlägt. Mit anderen Worten, ein Programm beginnt typischerweise mit mehreren sehr großen Löchern, die größten etwa 600 Megabyte. Zwischen den Zuordnungen, die zum Speichern von Code und Daten, die von der .NET-Laufzeitumgebung verwendet werden, und nicht verwalteten Windows-DLLs verfügbar sind, stehen Lücken zur Verfügung. Wenn das Programm mehr Speicher zuweist, werden diese Löcher kleiner. Es ist wahrscheinlich, etwas Speicher freizugeben, aber das reproduziert kein großes Loch. Sie erhalten normalerweise zwei Löcher, etwa die Hälfte der Größe des Originals, mit einer Zuteilung irgendwo in der Mitte, die das ursprüngliche große Loch in zwei schneidet.
Dies wird Fragmentierung, ein 32-Bit-Prozess genannt, die viel Speicher und gibt ordnet den virtuellen Speicheradressraum fragmentieren endet so das größte Loch, das noch verfügbar ist nach einer Weile, kleiner wird rund 90 Megabyte recht ist typisch.Die Anfrage nach 250 Megabyte wird fast garantiert fehlschlagen. Sie müssen niedriger zielen.
Sie haben zweifellos erwartet, dass es anders funktioniert, so dass die Summe von Zuweisungen bis zu 250 Megabyte funktioniert garantiert. Dies ist jedoch nicht, wie MemoryFailPoint funktioniert, es überprüft nur die größte mögliche Zuordnung. Unnötig zu sagen, vielleicht macht dies es weniger als nützlich. Ansonsten sympathisiere ich mit den .NET-Framework-Programmierern, da es so funktioniert, wie wir es gerne hätten, es ist teuer und kann keine Garantie geben, da die Größe einer Zuweisung am wichtigsten ist.
Virtueller Speicher ist eine reichliche Ressource, die unglaublich billig ist. Aber alles zu konsumieren ist sehr mühsam. Sobald Sie ein Gigabyte davon konsumiert haben, wird das zufällige OOM wahrscheinlicher. Vergessen Sie nicht die einfache Lösung für dieses Problem, Sie laufen auf einem 64-Bit-Betriebssystem. Wenn Sie also nur das Ziel der EXE-Plattform auf AnyCPU ändern, werden Sie im virtuellen Adressraum blödeln. Abhängig von der OS-Edition ist ein Terabyte möglich. Es zerbricht immer noch, aber es interessiert dich einfach nicht mehr, die Löcher sind riesig.
Last but not least, in den Kommentaren sichtbar, hat dieses Problem nichts mit RAM zu tun. Virtueller Speicher ist nicht verwandt mit der Menge an RAM, die Sie haben. Es ist die Aufgabe des Betriebssystems, virtuelle Speicheradressen physikalischen Adressen im RAM zuzuordnen, und zwar dynamisch. Zugriff auf einen Speicherort kann einen Seitenfehler auslösen, das Betriebssystem wird RAM für die Seite reservieren. Und umgekehrt passiert es, dass das Betriebssystem den RAM-Speicher für eine Seite auflöst, wenn sie anderweitig benötigt wird. Sie können niemals den Arbeitsspeicher verlassen, die Maschine wird langsamer, bevor das passieren kann. Das VMMap-Dienstprogramm von SysInternals ist gut zu sehen, wie der virtuelle Adressraum Ihres Programms aussieht, obwohl Sie dazu neigen, in den Informationen für einen großen Prozess zu ertrinken.
Was tun Sie noch, um diesen Fehler zu bekommen? Gibt es einen Stack-Trace, den Sie posten können? –
Ich habe Stack-Trace hinzugefügt, bitte Frage erneut beantworten –
"Ich überprüfte verfügbaren Speicher" wie? Sogar mit 1 GB frei, kann es zu fragmentiert sein, um eine Zuweisung von 250 Meg zuzuordnen. Es müsste 250M zusammenhängender freier Speicherplatz im Speicher vorhanden sein, damit dies erfolgreich ist. – spender