Announcement

Collapse
No announcement yet.

System.OutOfMemoryException beim Einlesen eines Strings

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • System.OutOfMemoryException beim Einlesen eines Strings

    Hallo,

    ich möchte eine Textdatei in einen String lesen, bekomme aber eine System.OutOfMemoryException bei 2.394MB RAM Nutzung, obwohl noch genug frei ist und die Anwendung für x64 auf einem 64-Bit PC läuft. Ich nutze VSTO 2015 Community und Windows 8.1.

    Hat jemand eine Idee, was ich übersehe?

    Gruß

    Lars

  • #2
    Ein Stream ist keine Option?

    Comment


    • #3
      Du meinst einen StreamReader? Ich würde die Datei gern komplett einlesen und dann mit regulären Ausdrücken zerlegen und in eine Datenbank schreiben. Wenn der Speicher frei ist, sollte er doch auch nutzbar sein?! Ansonsten bin ich für Alternativen offen, wenn Sie mich zum Ziel bringen.

      Comment


      • #4
        Wie groß ist die Textdatei?
        Wie sieht der Code zum einlesen aus?
        Grundsätzlich reicht es nicht, Speicher zur Verfügung zu haben, es muss auch zusammen hängender Speicher sein
        Christian

        Comment


        • #5
          Die Datei ist 1,15GB groß und der Code ist bisher schlicht gehalten - der Teil wo es knallt:

          Code:
           strDateiinhalt = File.ReadAllText(strQuelldatei, System.Text.Encoding.GetEncoding(1252))

          Comment


          • #6
            Würde vermuten, dass nicht genügend zusammen hängender Speicher vorhanden ist.
            Christian

            Comment


            • #7
              Würde vermuten, dass nicht genügend zusammen hängender Speicher vorhanden ist.
              Das würde ich auch vermuten und File.ReadAllText könnte es möglicherweise dazu noch selbst verursacht haben
              Um das eingrenzen zu können würde uns der StackTrace des Fehlers helfen. Mit dem genauen wo kann man das warum eher angehen und beheben.

              Comment


              • #8
                Glaube nicht, dass es sich lohnt den Fehler zu suchen. 1,15 GB. Und dann fallen u.U. beim zerlegen nochmals große Mengen von Teilstrings an. Das wäre dann der nächste Zeitpunkt wo Speichermangel auftreten könnte.
                Würde eher nach einer Lösung suchen, die mit einer teilweisen Bearbeitung der Datei (zeilenweise?) auskommt
                Christian

                Comment


                • #9
                  StackTrace Neuling - ich arbeite dran...

                  Comment


                  • #10
                    bei System.Text.StringBuilder.ToString()
                    bei System.IO.File.InternalReadAllText(String path, Encoding encoding, Boolean check Host)
                    bei Anwendungsname.Modulname.Main(String[] strArguments) in ... Zeile 26 welche wie oben angegeben lautet.

                    Comment


                    • #11
                      Das sieht mir nach der Methode selbst aus. Du wirst dir einen anderen Weg suchen müssen....
                      Christian

                      Comment


                      • #12
                        Das bestätigt zumindest das File.ReadAllText höchstwahrscheinlich ein Problem hat und nicht sonstiges im System Speicher belegt.
                        Du solltest wie am Anfang von dir selbst erwähnt einen StreamReader verwenden und das selbst machen und nicht File.ReadAllText benutzen. Zumindest nicht für Dateien in dieser Größe.

                        Und a.) wie Christian sagt am besten dann Blockweise die Datei bearbeiten und nicht versuchen die komplett im Speicher zu halten oder b.) wenn du unbedingt das Ganze als ein string im Speicher haben willst nicht StreamReader.ReadToEnd benutzen.
                        Ich habe mal eine andere ReadAlltext Methode angehängt der man die intern benutze buffergröße mitgeben kann. Die sollte du möglichst groß (aber nicht zu groß) an der Größe der Datei

                        [HIGHLIGHT=c#]public static string ReadAllText(string path, Encoding encoding, bool checkHost, long bufferSize)
                        {
                        StringBuilder stringBuilder = new StringBuilder(bufferSize);
                        using (StreamReader streamReader = new StreamReader(path, encoding, true, StreamReader.DefaultBufferSize, checkHost))
                        {
                        char[] array = new char[4096];
                        StringBuilder stringBuilder = new StringBuilder(bufferSize);
                        int charCount;
                        while ((charCount = this.Read(array, 0, array.Length)) != 0)
                        stringBuilder.Append(array, 0, charCount);
                        }
                        return stringBuilder.ToString();
                        }[/HIGHLIGHT]

                        Hintergrund die Implementierung von File.ReadAllText der der obigen sehr ähnlich ist (eigentlich habe ich die dort entnommen und angepasst) initialisiert den StringBuilder auch mit 4k. Du hast aber ein wesentlich größeres File. Heißt wenn die 4K überschritten sind muß ein größerer Buffer angelegt werden und das regelmäßig bis die Datei komplett in den StringBuilder passt. Das größeren Buffer anlegen und kleineren Buffer löschen führt letztendlich zur Fragmentierung des Speichers bis kein zusammenhängender Speicher passender Größe mehr gefunden werden kann. OutOfMemoryException heißt übrigens nicht zwingend das nicht genug Speicher vorhanden ist sondern nur das eine Speicher Anforderung keinen Speicher mehr herausrücken konnte und das kann viele Gründe haben.

                        Comment

                        Working...
                        X