我有一个C ++应用程序,我事先知道我期待大约1000个元素(有时甚至更多)来存储和处理数百个实例。 问题是进程使用的内存缓慢增加,但服务器的内存在几个小时内就不堪重负 我正在使用valgrind来检测最终的内存泄漏。
修改
首先,感谢大家的建议。我设法解决了很多错误。我在某些类中添加了虚拟析构函数,并使用reset更改了一些指向boost::shared_ptr
的指针以删除它们。但是,随着时间的推移,我的内存使用量仍在增加。
该应用程序的主要部分如下:
#ifdef GLOBAL
#define Global
#else
#define Global extern
#endif
typedef std::map<uint32_t, ResultStruct> ClassDResultMap ;
typedef std::map<uint32_t, ClassDResultMap > ClassCResultMap ;
typedef std::map<uint32_t, ClassCResultMap > ClassBResultMap ;
typedef std::map<uint32_t, ClassBResultMap > ClassAResultMap ;
Global ClassAResultMap classAresultmap;
ClassZero创建了许多ClassA
typedef std::map<uint32_t,ClassA*> classAMap;
classA_[aid] = new ClassA(io_service_, filename.c_str(), id, pri_queue_);
在ClassA内部,最多可创建3200个ClassB实例:
typedef std::map<uint32_t, boost::shared_ptr<ClassB >> classBMap ;
classBMap[aid].insert(std::pair<uint32_t, boost::shared_ptr<ClassB>>(bid, boost::make_shared<ClassB >(io_service_, pri_queue_, ...)));
在ClassB内部,在具有成员boost::shared_ptr<ClassC > classC_;
的ConfigMap结构中最多创建4个ClassC实例:
typedef std::map<uint32_t, classCConfig> ConfigMap;
(ConfigMap::iterator)->second.classC_ = boost::make_shared<ClassC >(io_service_, pri_queue_, ...);
在ClassC中,一个ClassD由ClassC构造函数
实例化ClassC::ClassC(...): ClassD(io_service_, pri_queue_,...),... { }
然后在ClassD内部,处理元素并且每10-30秒计算结果,而不是存储在ClassDResultMap中:
(ClassDResultMap::iterator)->second[results.stime] = results;
最后,在另一个类ClassStorage中,全局ClassAResultmap中的所有结果都保存到文件中并清除:
std::ofstream res_stream_;
res_stream_ << "{ \"start\" : " << results_it->second.stime << ...;
(ClassDResultMap::iterator)->second.clear();
std::map<uint32_t, ClassDResultMap>().swap((ClassDResultMap::iterator)->second);
这是我用Valgrind获得的A级A级:8级B:32级C / D
==9544== HEAP SUMMARY:
==9544== in use at exit: 25,817 bytes in 171 blocks
==9544== total heap usage: 148,771 allocs, 148,600 frees, 16,803,272 bytes allocated
==9544==
==9544== 1,216 bytes in 4 blocks are possibly lost in loss record 39 of 45
==9544== at 0x4C2677B: calloc (vg_replace_malloc.c:593)
==9544== by 0x40118A2: _dl_allocate_tls (in /lib64/ld-2.12.so)
==9544== by 0x5F971E8: pthread_create@@GLIBC_2.2.5 (in /lib64/libpthread-2.12.so)
==9544== by 0x4E3ACC0: boost::thread::start_thread_noexcept() (in /usr/local/lib/libboost_thread.so.1.54.0)
==9544== by 0x45EE92: boost::thread::start_thread() (thread.hpp:180)
==9544== by 0x461429: boost::thread::thread<boost::_bi::bind_t<unsigned long, boost::_mfi::mf0<unsigned long, boost::asio::io_service>, boost::_bi::list1<boost::reference_wrapper<boost::asio::io_service> > >&>(boost::_bi::bind_t<unsigned long, boost::_mfi::mf0<unsigned long, boost::asio::io_service>, boost::_bi::list1<boost::reference_wrapper<boost::asio::io_service> > >&) (thread.hpp:267)
==9544== by 0x4605F7: boost::thread* boost::thread_group::create_thread<boost::_bi::bind_t<unsigned long, boost::_mfi::mf0<unsigned long, boost::asio::io_service>, boost::_bi::list1<boost::reference_wrapper<boost::asio::io_service> > > >(boost::_bi::bind_t<unsigned long, boost::_mfi::mf0<unsigned long, boost::asio::io_service>, boost::_bi::list1<boost::reference_wrapper<boost::asio::io_service> > >) (thread_group.hpp:78)
==9544== by 0x45CAC9: main (main.cpp:151)
==9544==
==9544== LEAK SUMMARY:
==9544== definitely lost: 0 bytes in 0 blocks
==9544== indirectly lost: 0 bytes in 0 blocks
==9544== possibly lost: 1,216 bytes in 4 blocks
==9544== still reachable: 24,601 bytes in 167 blocks
==9544== suppressed: 0 bytes in 0 blocks
==9544== Reachable blocks (those to which a pointer was found) are not shown.
==9544== To see them, rerun with: --leak-check=full --show-reachable=yes
==9544==
==9544== For counts of detected and suppressed errors, rerun with: -v
==9544== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6)
以及Valgrind抱怨的main.cpp部分:
boost::asio::io_service work_io_service;
ClassZero manager(work_io_service);
boost::thread_group work_threads;
uint32_t workers = boost::thread::hardware_concurrency();
for (std::size_t i = 0; i != workers; ++i)
{
work_threads.create_thread(
boost::bind(&boost::asio::io_service::run, boost::ref(work_io_service)));
}
我的问题是,在将近20分钟内,服务器内存(4GB)从3%增加到17%并继续运行。进程内存使用量正在增加但仍低于4%!