StringBuilder.ToString () löst OutOfMemoryException aus

7

Ich habe eine StringBuilder der Länge "132370292" erstellt, wenn ich versuche, die Zeichenfolge mit der Methode ToString() zu erhalten, die OutOfMemoryException auslöst.

%Vor%

Was ist der Grund für das OOM beim Erstellen einer neuen Zeichenfolge und warum es OOM beim Schreiben in eine Datei nicht auslöst?

Maschinendetails: 64-Bit, Windows-7, 2 GB RAM Hinweis: .NET Version 2.0

    
Thiru 29.07.2014, 07:56
quelle

3 Antworten

16
  

Was ist der Grund für das OOM beim Erstellen einer neuen Zeichenfolge?

Weil Ihnen nicht mehr genug Speicher zur Verfügung steht - oder zumindest kann die CLR kein Objekt mit der von Ihnen angeforderten Größe zuweisen. Es ist wirklich so einfach. Wenn Sie die Fehler vermeiden möchten, versuchen Sie nicht, Zeichenfolgen zu erstellen, die nicht in den Speicher passen. Beachten Sie, dass die Größe von Objekten, die erstellt werden können, selbst dann begrenzt ist, wenn Sie über viel Speicher verfügen und selbst wenn Sie eine 64-Bit-CLR ausführen.

  

und warum wird OOM beim Schreiben in eine Datei nicht geworfen?

Weil Sie mehr Speicherplatz als Speicher haben.

Ich bin mir ziemlich sicher, dass der Code nicht ist, wie Sie es beschreiben. Diese Zeile konnte nicht kompiliert werden:

%Vor%

... weil die Methode Write ist und nicht write . Und wenn Sie tatsächlich aufrufen und SB.ToString() aufrufen, dann ist das ebenso wahrscheinlich wie str = SB.ToString() .

Es ist wahrscheinlicher, dass Sie tatsächlich stream in die Datei schreiben, z. B.

%Vor%

Auf diese Weise müssen Sie nie große Mengen an Text im Speicher haben - es wird einfach auf die Festplatte geschrieben, möglicherweise mit einige Pufferung, aber nicht genug, um Speicherprobleme zu verursachen.

>     
Jon Skeet 29.07.2014, 07:59
quelle
6

Workaround: Angenommen, Sie möchten eine große Zeichenfolge, die in StringBuilder gespeichert ist, in einen StreamWriter schreiben, würde ich auf diese Weise schreiben, um die OOM-Ausnahme von SB.ToString zu vermeiden. Aber wenn Ihre OOM-Ausnahme auf den Inhalt von StringBuilder selbst zurückzuführen ist, sollten Sie daran arbeiten.

%Vor%     
Titus 05.09.2015 13:43
quelle
2

Sie müssen daran denken, dass Strings in .NET im 16-Bit-Unicode gespeichert werden. Dies bedeutet, dass die Zeichenfolge der Länge 132370292 260 MB RAM erfordert.

Außerdem während der Ausführung

%Vor%

Sie erstellen eine Kopie Ihrer Zeichenfolge (weitere 260 MB).

Denken Sie daran, dass jeder Prozess sein eigenes RAM-Limit hat, so dass OutOfMemoryException ausgelöst werden kann, selbst wenn Sie noch etwas freien RAM haben.

    
semao 29.07.2014 08:07
quelle