7


正如主题所暗示的那样,在将大量数据序列化到文件时,我遇到了 boost::serialization 的一个小问题。问题在于应用程序的序列化部分的内存占用大约是被序列化对象内存的 3 到 3.5 倍。
重要的是要注意,我拥有的数据结构是基类指针的三维向量和指向该结构的指针。像这样:

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

稍后将使用与此类似的代码对其进行序列化:

ar & BOOST_SERIALIZATION_NVP(data);

包括 boost/serialization/vector.hpp。

被序列化的类都继承自“MyBase”。
现在,自从我的项目开始以来,我使用不同的档案进行序列化,从典型的 binary_archive、text、xml 到最后的多态 binary/xml/text。这些中的每一个都以完全相同的方式起作用。

通常,如果我必须序列化少量数据,但我拥有的类数量为数百万(理想情况下约为 1000 万),并且我能够测试的内存使用情况始终如一地表明,这通常不会成为问题boost::serialization 部分代码分配的内存大约是写入文件时应用程序整个内存占用的 2/3。

这相当于为 400 万个对象占用了大约 13.5 GB 的 RAM,而对象本身占用了 4.2 GB。现在这是我能够使用我的代码的最大范围,因为我无法访问具有超过 8GB 物理 RAM 的机器。我还应该注意,这是一个在 Windows 7 专业 x64 版本上运行的 64 位应用程序,但在 Ubuntu 机器上情况类似。

任何人都知道我将如何解决这个问题,因为我无法接受对一个应用程序有如此高的内存要求,它在运行时不会像在序列化时那样使用那么多内存。

反序列化并没有那么糟糕,因为它分配了大约 1.5 倍所需内存。这是我可以忍受的。

尝试使用 boost::archive::archive_flags::no_tracking 关闭跟踪,但它的作用完全相同。

有人知道我应该怎么做吗?

4

1 回答 1

1

使用 valgrind 我发现内存消耗的主要原因是库中用于跟踪指针的映射。如果您确定不需要指针跟踪(这意味着您确定没有指针混叠)禁用跟踪。您可以在此处找到禁用跟踪的主要概念。简而言之,您必须执行以下操作:

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

我的问题中,我编写了这个宏的一个版本,您可以禁用对模板类的跟踪。这一定会对您的内存消耗产生重大影响。另请注意,任何容器内都有指针如果您不想跟踪,您也必须禁用对它们的跟踪。目前我找不到任何方法来正确地做到这一点。

于 2016-02-17T06:02:59.417 回答