2009-04-02 6 views
2

Ich verwende Serialisierung für "Speichern" -Feature in meiner Anwendung. Aber wenn die Daten zu groß sind (15+ MB), fange ich an, OutOfMemory-Ausnahmen zu bekommen.Wie große Objekte in .NET serialisieren? (OutOfMemory Exceptions)

Ich habe so viele Objekte und sie sind mit anderen kleinen Objekten verbunden, ich denke, das verursacht zu viel Rechenleistung und Daten im Speicher.

Mein Code wird auf dieser Basis, fast gleich:

http://www.codeproject.com/KB/vb/TreeViewDataAccess.aspx

Edit:

  1. ich benutzerdefinierte Serialisierung nicht verwenden, es ist alles getan, indem [Serialisierung] Attribute . Einige Felder ausschließen.

  2. Ich serialisieren so viele Objekte und benutzerdefinierte Klassen. Enthält Wörterbuch, Strukturen und eine Menge anderer Sachen.

  3. Ich serialisieren es in eine Datei.

  4. Ich verwende XmlSerializer

P. S. Ich habe 4 GB physischen Speicher.

Lösung

Dank Antworten wurde mein Problem mit XmlSerializer sein gefunden und ich habe loswerden es. Binäre Serialisierung funktioniert gut mit den Daten, die ich habe.

+0

Welche Art von Objekt ist das? Und welches Serialisierungsframework verwenden Sie? Sind die Daten ein Baum? oder ein Graph? (d. h. gibt es mehr als eine Route zu irgendeinem Objekt)? –

+0

Es ist so viele verknüpfte Objekte einschließlich viele benutzerdefinierte Klassen sowie eine Baumansicht :) –

+0

Ich verwende kein spezielles Framework mit .NET-Serialisierung (.NET Framework 2.0). –

Antwort

1

15MB sollte Ihnen kein OOM geben.

Wenn die Daten baumartig sind (statt einer vollständigen Grafik), könnten Sie einen Serializer wie protobuf-net; Es nutzt nicht nur das sehr effiziente binäre "Protokollpuffer" -Format von Google (sowohl Geschwindigkeit als auch Arbeitsspeicher), es benötigt auch kein Referenz-Tracking (wird für Grafiken benötigt) - das bedeutet, dass es sich nur einmal um Daten kümmern muss (zweimal wenn dies der Fall ist) gepuffert werden).

Dies erfordert jedoch unterschiedliche Markup für Ihre Klassen (oder zumindest ein "Opt-in") - und es wird nicht vollständige Grafiken behandeln. Aber es ist da und frei ...

+0

Ich habe gerade die Code-Ausnahme überprüft, die im XmlSerializer passiert ist - dieser Teil des Codes basiert auf diesem: http://www.codeproject.com/KB/vb/TreeViewDataAccess.aspx –

0

Sie könnten Ihre eigenen Serialisierungsroutinen schreiben und sehen, ob Sie durch die manuelle Anpassung Ihres Serialisierungsprozesses Leistungsvorteile erzielen können. Weitere Details finden Sie unter MSDN page on Custom Serialization.

0

Vielleicht können Sie uns ein bisschen mehr Details darüber geben, wie die Serialisierung gemacht wird. Verwenden Sie eine benutzerdefinierte Serialisierung? Oder verwenden Sie einfach das integrierte Attribut [Serialisierung]?

Ich denke, dass ein guter Weg für Sie, dies zu tun ist zu versuchen, Ihre benutzerdefinierte Serialisierungslogik zu tun und nur nur was Sie brauchen serialisieren, es kann nicht auf 4GB gehen, es hängt auch davon ab, wie viel Memeory Ihre Anwendung hat zugewiesen.

+0

.NET verwaltet den Speicher, richtig? Also habe ich keine Kontrolle darüber. Ich nehme an, wenn die App mehr als 1GB App geht wird in der Regel instabil. Gibt es überhaupt noch Speicherplatz für meine App? –

+0

@Slough - naja, du könntest zu x64 gehen und eine Menge Speicher hineinschieben; aber das fühlt sich an, als ob es nicht notwendig sein sollte. –

2

Eigentlich ignoriert XmlSerializer die SerializableAttribute-Attribute. Sie werden nur von den Formatierungsklassen (BinaryFormatter, SoapFormatter) verwendet.

Ich würde nicht mit dem XmlSerializer serialisieren, und vor allem keine Kombination von XmlSerializer und BinaryFormatter.

Ich würde einfach versuchen, alles mit dem BinaryFormatter zu serialisieren.

+0

Ich denke, das macht Sinn. Ich habe es benutzt, weil jemand bereits den Code für persistenten Treeview-Speicher geschrieben hat.Wie auch immer, ich werde versuchen, es durch Binaryformatter zu ersetzen, und sehen, ob es funktioniert. –

0

Mit all den Ansätzen, die hier erwähnt werden, geht die Leichtigkeit des Dumpings großer Objekte auf die Festplatte und Wiederherstellung verloren. Außerdem unterstützen diese nur Dump-Datentypen. Daher können Referenztypen nicht so einfach wie mit BinaryFormatter ausgegeben werden.

Auch die Komprimierung mit gzip oder 7-Zip vor der binären Formatierung von großen Objekten tatsächlich bewegen die Größe über 16 MB zu etwas wie 32 MB.

3

Ich hatte genau das gleiche Problem. Der Grund ist, dass .NET Serialisierung nicht skaliert.

löste ich das Problem von Simon Hewitt ausgezeichnete offene -Source-Bibliothek verwenden, Optimizing Serialization in .NET - part 2 sehen.

Neben der drastischen Reduzierung der Speicherauslastung ist es auch viel schneller . Ähnlich wie beim Artikel habe ich eine Beschleunigung von 20 Mal bekommen.

0

Sie könnten herunterladen JSON.NET Bibliothek, die in meinem Projekt mehr als 100 MB Daten Serialisierung und Deserialisierung funktioniert.

für die Serialisierung können Sie wie

arbeiten Wenn Sie Object Verwendung Textwriter

using (TextWriter textWriter = File.CreateText("LocalJsonFile.json")) 
{ 
    var serializer = new JsonSerializer(); 
    serializer.Serialize(textWriter , yourObject); 
} 

haben Wenn Sie Zeichenfolge Verwendung String

StringBuilder sb = new StringBuilder(); 
    StringWriter sw = new StringWriter(sb); 

    using(JsonWriter textWriter = new JsonTextWriter(sw)) 
    { 
    var serializer = new JsonSerializer(); 
    serializer.Serialize(textWriter, yourObject); 
    } 

Dies kann für Sie arbeiten.