Großes string-array, wodurch die out-of-memory-Ausnahme (C#)

Ich geschrieben habe ein c# win-forms-Anwendung, die dem Benutzer ermöglicht, öffnen Sie eine log - (text -) Datei und das log-Zeilen in einem Daten-grid. Die Anwendung, die Formate, die log-Daten, so dass die Benutzer können filter, Suche etc.

Das problem, das ich habe, ist, dass, wenn der Benutzer öffnet eine log-Datei - > 300mb löst die Anwendung eine out-of-memory-Ausnahme.

Die erste app lädt alle log-Zeilen in ein string-array, dann durchläuft es die log-Zeilen, das hinzufügen von log-Eintrag-Objekte zu einer Liste.

var allLogLines = File.ReadAllLines(logPath).ToList();
var nonNullLogLines = allLogLines.Where(l => !string.IsNullOrEmpty(l));

this.ParseLogEntries(nonNullLogLines.ToArray());

Dieser erste Schritt (das laden der log-Daten in einem string-array) verwendet, die bis zu 1 GB Speicher im task-manager.

internal override void ParseLogEntries(string[] logLines)
{
    this.LogEntries = new List<LogEntry>();
    this.LogLinesCount = logLines.Count();

    for (int i = 0; i < this.LogLinesCount; i++)
    {
        int entryStart = this.FindMessageCompartment(logLines, i);
        int entryEnd = this.FindMessageCompartment(logLines, entryStart + 1);
        int entryLength = (entryEnd - entryStart) + 1;

        if (entryStart + entryLength > this.LogLinesCount)
        {
            entryLength = this.LogLinesCount - entryStart;
        }

        var logSection = new string[entryLength];

        Array.Copy(logLines, entryStart, logSection, 0, entryLength);
        Array.Clear(logLines, i, entryLength - 1);

        this.AddLogEntry(logSection);

        i = (entryEnd - 1);
    }
}

Den AddLogEntry Methode addes einen log-Eintrag in der Liste (Logeinträge). Die for-Schleife verwaltet, analysiert über 50% der log-Datei, dann die out-of-memory-Ausnahme Auftritt. An diesem Punkt task-manager meldet, dass die Anwendung ist mit über 1,3 gb Speicher.

Wie Sie sehen können, habe ich oben Hinzugefügt Array.Klar, zu null aus dem Teil der log-Daten wurden erfolgreich analysiert, als Ergebnis würde ich erwarten, dass als Objekte der Auflistung Hinzugefügt wird, die Menge an Arbeitsspeicher (1 GB, um mit zu beginnen) verwendet, die durch die große log-Daten-array würde stetig reduzieren, muss es aber nicht. in der Tat ist diese Zeile macht keinen Unterschied,, um die Speicherauslastung, auch wenn ich ein GC sammeln in regelmäßigen Abständen.

Gelesen über LOH, ich gehe davon aus, dass dies ist, weil der heap wird nicht komprimiert, wie Teile der großen Auswahl wird zurückgesetzt, so dass es verwendet immer die gleiche 1 GB Speicher trotz seiner Inhalte.

Gibt es eine Möglichkeit, kann ich reduzieren die Menge an Speicher gehalten, während die Daten analysiert wird, oder eine mögliche Nacharbeit, die eventuell bessere Nutzung der Speicher? Es scheint mir seltsam, dass eine 300mb text-Datei, wenn man Sie in einem string-array, verbraucht 1 GB Speicher?

Dank.

  • Was ist FindMessageCompartment? Auch nicht mit arrays, verwenden Sie die generische List<string>
  • irgendwelche probs zu tun ReadLine ich.e Lesen Zeile für Zeile und-Verarbeitung-Datei? Anstatt laden Sie alle auf einmal.
  • Ist dies passiert, bevor Sie Ihnen zeigen, Daten, die nur während der Analyse?
  • Wie Sie Lesen Sie die Datei verwenden Sie StramReader.ReadLine()?
  • Welche version von .NET? .NET-4 bietet effiziente Methoden für die Datei-Zeilen auflisten, ohne das abrufen aller Zeilen in Speicher
  • Seine .net 3.5. Die Datei enthält separator strings, bezeichnen das Ende der log-Abschnitt, FindMessageCompartment sucht den index der separator. Dies geschieht, bevor alle Daten angezeigt, wenn der Benutzer klickt auf "Load File".

InformationsquelleAutor RobJohnson | 2012-01-05
Schreibe einen Kommentar