4 Stimmen

Speicherverwaltung in C#

Guten Tag,

Ich habe einige Textdateien mit einer Liste von (2-Gramm, Anzahl) Paaren, die durch die Analyse eines Korpus von Zeitungsartikeln gesammelt wurden und die ich in den Speicher laden muss, wenn ich eine bestimmte Anwendung, die ich entwickle, starte. Um diese Paare zu speichern, verwende ich eine Struktur wie die folgende:

private static Dictionary<String, Int64>[] ListaDigramas = new Dictionary<String, Int64>[27];

Die Idee, ein Array von Wörterbüchern zu haben, ist auf Effizienzfragen zurückzuführen, da ich irgendwo gelesen habe, dass ein langes Wörterbuch einen negativen Einfluss auf die Leistung hat. Davon abgesehen wird jedes 2-Gramm in das Wörterbuch aufgenommen, das dem ASCII-Code des ersten Zeichens minus 97 entspricht (oder 26, wenn das erste Zeichen kein Zeichen im Bereich von "a" bis "z" ist).

Wenn ich die (2-Gramm-, Zähl-)Paare in den Speicher lade, nimmt die Anwendung insgesamt 800 MB RAM in Anspruch, und das bleibt so, bis ich ein Programm namens Memory Cleaner verwende, um Speicher freizugeben. Danach sinkt der Speicherbedarf des Programms auf 7 MB bis 100 MB, ohne dass die Funktionalität beeinträchtigt wird (glaube ich).

Gibt es eine Möglichkeit, auf diese Weise Speicher freizugeben, ohne eine externe Anwendung zu verwenden? Ich habe versucht, Folgendes zu verwenden GC.Collect() aber in diesem Fall funktioniert es nicht.

Ich danke Ihnen vielmals.

0voto

James Punkte 77534

Wenn Sie Ihre Anwendungsressourcen ordnungsgemäß entsorgen, wird die tatsächliche gebraucht Speicher ist möglicherweise nicht das, was Sie sehen (wenn Sie es mit dem Task-Manager überprüfen).

Der Garbage Collector wird den ungenutzten Speicher zum bestmöglichen Zeitpunkt freigeben. Es ist normalerweise auch keine gute Idee, die Sammlung zu erzwingen... siehe dies Beitrag

"Daten müssen tatsächlich während der gesamten Laufzeit der Anwendung geladen werden. - Warum?

0voto

James King Punkte 6082

Die einzige andere Idee, die mir einfiel, wenn Sie den Speicherverbrauch wirklich niedrig halten wollen, wäre, das Wörterbuch in einem Stream zu speichern und zu komprimieren. Dabei ist zu berücksichtigen, wie oft Sie auf diese Daten zugreifen und wie komprimierbar die Daten sind. Text aus Zeitungsartikeln lässt sich sehr gut komprimieren, und die Leistungseinbußen könnten geringer sein, als Sie denken.

Die Verwendung einer Open-Source-Bibliothek wie SharpZipLib ( http://www.icsharpcode.net/opensource/sharpziplib/ ), würde Ihr Code etwa so aussehen:

MemoryStream stream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();

formatter.Serialize(stream, ListaDigramas);
byte[] dictBytes = stream.ToArray();

Stream zipStream = new DeflaterOutputStream(new MemoryStream());
zipStream.Write(dictBytes, 0, dictBytes.Length);

Das Aufblasen erfordert eine InflaterInputStream und eine Schleife zum Aufblasen des Datenstroms in Teilen, aber es ist ziemlich einfach.

Man muss mit der App spielen, um zu sehen, ob die Leistung akzeptabel ist. Dabei muss man natürlich bedenken, dass man immer noch genügend Speicherplatz für das Wörterbuch benötigt, wenn man es für die Verwendung aufbläst (es sei denn, jemand hat eine clevere Idee, mit dem Objekt in seinem komprimierten Zustand zu arbeiten).

Ehrlich gesagt ist es aber wahrscheinlich die beste/schnellste Option, die Datei im Speicher zu belassen und sie von Windows in die Auslagerungsdatei auslagern zu lassen.

bearbeiten
Ich habe es nie versucht, aber Sie könnten in der Lage sein, direkt in den Kompressionsstrom zu serialisieren, was bedeutet, dass der Kompressions-Overhead minimal ist (Sie würden immer noch den Serialisierungs-Overhead haben):

MemoryStream stream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();

Stream zipStream = new DeflaterOutputStream(new MemoryStream());

formatter.Serialize(zipStream, ListaDigramas);

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