【问题标题】:boost serialization binary_oarchive crashes提升序列化 binary_oarchive 崩溃
【发布时间】:2012-08-26 22:55:30
【问题描述】:

首先,我要填充一个很大且相互关联的结构。然后我将其序列化为二进制存档。该结构的大小取决于我向程序提供的数据。我看到程序占用了大约 2GB 内存来构建预期和可接受的结构。

然后我开始序列化对象。我看到程序在序列化时吃掉了 RAM。 RAM 使用量不断增长,直到接近 100%。交换使用量仍为 0 字节。

然后应用程序崩溃。除了bad_allocnew上的new

为什么序列化过程会占用如此多的 RAM 和时间?为什么在交换为空时分配内存时会崩溃?回溯太长,无法完整粘贴。

#0  0xb7fe1424 in __kernel_vsyscall ()
#1  0xb7c6e941 in raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#2  0xb7c71e42 in abort () at abort.c:92
#3  0xb7e92055 in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/libstdc++.so.6
#4  0xb7e8ff35 in ?? () from /usr/lib/libstdc++.so.6
#5  0xb7e8ff72 in std::terminate() () from /usr/lib/libstdc++.so.6
#6  0xb7e900e1 in __cxa_throw () from /usr/lib/libstdc++.so.6
#7  0xb7e90677 in operator new(unsigned int) () from /usr/lib/libstdc++.so.6
#8  0xb7f00a9f in boost::archive::detail::basic_oarchive_impl::save_pointer(boost::archive::detail::basic_oarchive&, void const*, boost::archive::detail::basic_pointer_oserializer const*) () from /usr/lib/libboost_serialization.so.1.42.0
#9  0xb7effb42 in boost::archive::detail::basic_oarchive::save_pointer(void const*, boost::archive::detail::basic_pointer_oserializer const*) () from /usr/lib/libboost_serialization.so.1.42.0
#10 0x082d052c in void boost::archive::detail::save_pointer_type<boost::archive::binary_oarchive>::non_polymorphic::save<gcl::NestedConnection<gcl::Section, gcl::NestedConnection<gcl::Paragraph, gcl::NestedConnection<gcl::Line, void> > > >(boost::archive::binary_oarchive&, gcl::NestedConnection<gcl::Section, gcl::NestedConnection<gcl::Paragraph, gcl::NestedConnection<gcl::Line, void> > >&) ()
#11 0x082d0472 in void boost::archive::detail::save_pointer_type<boost::archive::binary_oarchive>::save<gcl::NestedConnection<gcl::Section, gcl::NestedConnection<gcl::Paragraph, gcl::NestedConnection<gcl::Line, void> > > >(boost::archive::binary_oarchive&, gcl::NestedConnection<gcl::Section, gcl::NestedConnection<gcl::Paragraph, gcl::NestedConnection<gcl::Line, void> > > const&) ()

.......

#172 0x082a91d8 in boost::archive::detail::interface_oarchive<boost::archive::binary_oarchive>::operator<< <gcl::Collation const> (this=0xbfffe500, t=...) at /usr/include/boost/archive/detail/interface_oarchive.hpp:64
#173 0x082a6298 in boost::archive::detail::interface_oarchive<boost::archive::binary_oarchive>::operator&<gcl::Collation> (this=0xbfffe500, t=...) at /usr/include/boost/archive/detail/interface_oarchive.hpp:72
#174 0x0829bd63 in main (argc=4, argv=0xbffff3f4) at /home/neel/projects/app/main.cpp:93
  • 当输入较小的数据时,程序可以正常工作。
  • 使用 64 位 Linux 和 32 位 PAE 内核 boost 1.42
  • 程序在几次修订前运行时没有崩溃。我最近在结构中添加了更多字节。可能那时它还没有到达 RAM 的尽头,而现在它已经到达了。

但是当有足够的 swap 时,为什么 new 会崩溃?为什么序列化过程会占用这么多内存?

【问题讨论】:

  • 174 行并不算长(尽管确实跟踪可能不是很有趣)。但是,如果不了解数据结构(最好是:实际代码),我们可以看到的并不多,我猜......
  • 我实际上在做的是解析结构中的几个文本文件,然后在它们之间进行 N:N 比较。并获取连接对象。我正在序列化两者。它不是一个单行程序。应用程序非常庞大,无法在此处粘贴其代码。
  • 您是否尝试过任何其他存档类型,例如文本或 XML?
  • 不,我试过了。但这主要是二进制数据,值得一试吗?

标签: c++ boost archive boost-serialization


【解决方案1】:

问题:为什么swap为空时分配内存时会崩溃?

分配的对象太大,无法容纳virtual address space中的任何位置:

如果您的应用程序被编译为 32 位,则进程 virtual address space 被限制为 4Gb。

问题:为什么序列化过程会占用这么多内存?

我没有找到任何证据。

【讨论】:

    【解决方案2】:

    我意识到序列化过程占用了额外的内存,用于自己的内务处理。那就是3GB Barrier 为了阻止序列化过程占用额外的内存,我禁用了对象跟踪BOOST_CLASS_TRACKING 并修复了额外的内存开销。

    【讨论】:

      猜你喜欢
      • 2012-03-22
      • 1970-01-01
      • 2011-09-06
      • 1970-01-01
      • 2015-09-22
      • 2012-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多