2010-12-29 12 views
7


gerade wie das Thema suggeriert Ich bin auf ein kleines Problem mit Boost :: Serialisierung beim Serialisieren einer großen Menge von Daten in eine Datei gestoßen. Das Problem besteht darin, dass der Speicher-Footprint des Serialisierungsteils der Anwendung etwa das 3 bis 3,5-fache des Speichers meiner Objekte benötigt, die serialisiert werden.
Es ist wichtig zu beachten, dass die Datenstruktur, die ich habe, ein dreidimensionaler Vektor von Basisklassenzeigern und ein Zeiger auf diese Struktur ist. Wie folgt aus:Boost :: Serialisierung hoher Speicherverbrauch während der Serialisierung

using namespace std;  
vector<vector<vector<MyBase*> > >* data; 

Dies wird später mit einem Code analog zu diesem serialisiert:

ar & BOOST_SERIALIZATION_NVP(data); 

boost/Serialisierung/vector.hpp enthalten ist.

Klassen, die serialisiert werden, erben alle von "MyBase".
Jetzt, seit dem Start meines Projekts habe ich verschiedene Archive für die Serialisierung von typischen binary_archive, text, xml und schließlich polymorphe binary/xml/text verwendet. Jeder einzelne davon verhält sich genau gleich.

Normalerweise wäre dies kein Problem, wenn ich kleine Datenmengen serialisieren müsste, aber die Anzahl der Klassen, die ich habe, liegt in den Millionen (idealerweise etwa 10 Millionen) und der Speicherverbrauch, wie ich es testen konnte zeigt konsistent, dass der vom boost :: serialization-Teil des Codes zugewiesene Speicher ungefähr 2/3 des gesamten Speicherbedarfs der Anwendung beim Schreiben der Datei ausmacht.

Dies entspricht etwa 13,5 GB RAM für 4 Millionen Objekte, wobei die Objekte selbst 4,2 GB benötigen. Jetzt ist das so weit, wie ich meinen Code nehmen konnte, da ich keinen Zugriff auf eine Maschine mit mehr als 8 GB physikalischem RAM habe. Ich sollte auch beachten, dass dies eine 64-Bit-Anwendung ist, die auf einer professionellen Windows 7 x64-Edition ausgeführt wird, aber die Situation ist ähnlich auf einer Ubuntu-Box.

Jeder hat eine Idee, wie ich mich um die Fehlerbehebung kümmern würde, da es für mich inakzeptabel ist, so hohe Speicheranforderungen für eine Anwendung zu haben, die während des Betriebs nicht so viel Speicher verbraucht wie bei der Serialisierung.

Deserialisierung ist nicht so schlecht, da es rund 1,5 mal den benötigten Speicher reserviert. Damit könnte ich leben.

Versuchte Drehen mit boost :: archive :: archive_flags :: no_tracking deaktivieren, aber es verhält sich genau gleich.

Hat jemand eine Idee, was ich tun soll?

+0

Einfach einchecken, um das Thema zu stoßen, da noch niemand geantwortet hat ... – Max021

+0

Interessantes Thema. Lesen Sie dies: http: // stackoverflow.com/questions/1058051/boost-serialisierung-performance-text-vs-binary-format –

+0

Die 'no_tracking'-Flag ist leider nicht implementiert (es gibt einige Diskussionen über den Issue Tracker darüber)./cc @MohsenTamiz – sehe

Antwort

1

Mit Valgrind habe ich herausgefunden, dass der Hauptgrund für den Speicherverbrauch eine Karte innerhalb der Bibliothek ist, um Zeiger zu verfolgen. Wenn Sie sicher sind, dass Sie kein Pointer-Tracking benötigen (dh, dass Sie sicher sind, dass kein Pointer-Aliasing vorhanden ist), deaktivieren Sie das Tracking. Sie können here die wichtigsten Konzepte der Deaktivierung von Tracking finden. Kurz gesagt müssen Sie etwas tun:

BOOST_CLASS_TRACKING(vector<vector<vector<MyBase*> > >, boost::serialization::track_never) 

In my question Ich schrieb eine Version dieses Makro, das Sie Tracking einer Template-Klasse deaktivieren könnte. Dies muss einen erheblichen Einfluss auf Ihren Speicherverbrauch haben. Beachten Sie auch, dass sich in den Containern Zeiger befinden. Wenn Sie nie ein Tracking wünschen, müssen Sie auch deren Tracking deaktivieren. Momentan konnte ich keine Möglichkeit finden, dies richtig zu machen.

+0

Es sei denn, Sie brauchen das Tracking natürlich. (Sie können mehr Speicher sparen, indem Sie die Serialisierung deaktivieren). Die wirkliche Lösung hier wäre, keine Zeigerserialisierung zu verwenden. – sehe

+0

Upvoted für das "nette" Makro für Template-Klassen (nun, es ist ein Makro; ich habe bis jetzt immer Teilspezialisierung benutzt) – sehe