boost :: serialization высокое потребление памяти во время сериализации - PullRequest
7 голосов
/ 30 декабря 2010


так же, как предполагается в теме, я столкнулся с небольшой проблемой с boost :: serialization при сериализации огромного количества данных в файл. Проблема состоит в том, что объем памяти, используемой частью приложения для сериализации, занимает от 3 до 3,5 раз больше памяти, чем мои объекты, которые сериализуются.
Важно отметить, что имеющаяся у меня структура данных - это трехмерный вектор указателей базового класса и указатель на эту структуру. Как это:

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

Это позже сериализуется с кодом, аналогичным этому:

ar & BOOST_SERIALIZATION_NVP(data);

boost / serialization / vector.hpp включен.

Все сериализуемые классы наследуются от "MyBase".
Теперь, с момента запуска моего проекта, я использовал различные архивы для сериализации из типичного двоичного_архива, текста, xml и, наконец, полиморфного двоичного файла / xml / text. Каждый из них действует точно так же.

Как правило, это не было бы проблемой, если бы мне пришлось сериализовать небольшие объемы данных, но количество классов, которые у меня есть, исчисляется миллионами (в идеале около 10 миллионов), а использование памяти, как я смог протестировать, показывает, что память, выделенная частью кода boost :: serialization, составляет около 2/3 всей памяти приложения при записи файла.

Это составляет около 13,5 ГБ ОЗУ для 4 миллионов объектов, а сами объекты занимают 4,2 ГБ. Теперь я могу взять свой код, поскольку у меня нет доступа к машине с более чем 8 ГБ физической памяти. Я также должен отметить, что это 64-битное приложение, работающее под управлением Windows 7 Professional x64 Edition, но на Ubuntu ситуация аналогична.

Любой знает, как мне решить эту проблему, поскольку для меня неприемлемо иметь такие высокие требования к памяти для приложения, которое не будет использовать столько памяти при работе, сколько при сериализации.

Десериализация не так плоха, так как она выделяет примерно в 1,5 раза больше необходимой памяти. Это то, с чем я мог бы жить.

Попытался отключить отслеживание с помощью boost :: archive :: archive_flags :: no_tracking, но он действует точно так же.

Кто-нибудь знает, что мне делать?

1 Ответ

1 голос
/ 17 февраля 2016

Используя valgrind, я обнаружил, что основной причиной потребления памяти является карта внутри библиотеки для отслеживания указателей. Если вы уверены, что вам не нужно отслеживание указателя (это означает, что вы уверены, что нет псевдонима указателя) отключите отслеживание. Вы можете найти здесь основные концепции отключения отслеживания. Короче говоря, вы должны сделать что-то вроде этого:

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

В мой вопрос Я написал версию этого макроса, чтобы вы могли отключить отслеживание класса шаблона. Это должно оказать значительное влияние на потребление памяти. Также обратите внимание, что внутри любых контейнеров есть указатели. Если вы не хотите отслеживать, вы также должны отключить их отслеживание. В настоящее время я не могу найти способ сделать это правильно.

...