log4cpp退出时内存泄露的修复方案
1.缘由
一直对log4cpp非常有好感,就在自己的项目中集成了log4cpp1.1.1版本,并围绕着它建立了一系列的封装函数方便外部调用。写完了一个测试代码后,忽然想看看自己写的程序有没有内存泄露问题。在打开了内存检查参数后发现,有程序退出时有不少内存没有释放。由于我的测试程序很小,所以很快就定位到了原来是log4cpp退出时有Appender对象没有释放。拿起谷歌搜了一把网上没有很好的解决方案,本着自己动手丰衣足食的方法,自己动手调整了下代码,到目前为止暂时没有发现新问题。废话不多说了,直接上修改步骤。
2.修改步骤
2.1.在Appender.hh的Appender类中添加公共静态函数
static void destroyAppender();
2.2.在Appender.cpp中实现添加的函数
void Appender::destroyAppender()
{
Appender::closeAll();
Appender::_deleteAllAppenders();
delete _allAppenders;
_allAppenders = nullptr;
}
2.3.修改Appender::_deleteAllAppenders()函数
按照以上方案修改后,你会发现执行到_deleteAllApenders()函数会导致崩溃,原因是在于Appender的析构函数中会修改容器,因此需要对该函数做出微调
void Appender::_deleteAllAppenders() {
threading::ScopedLock lock(_appenderMapMutex);
AppenderMap& allAppenders = _getAllAppenders();
size_t nCount=allAppenders.size();
for(AppenderMap::iterator i = allAppenders.begin(); nCount>0; --nCount) {
Appender *app = (*i).second;
i++; // increment iterator before delete or iterator will be invalid.
delete (app);
}
}
可以看到我是用一个数量来控制循环的结束。注意循环退出以后,再也不要操作allAppenders容器了,不然还是崩溃。
2.4.增加退出清理事件
在HierarchyMaintainer的构造函数中,把我们自己新建的函数注册到退出回调,代码如下
HierarchyMaintainer::HierarchyMaintainer() {
register_shutdown_handler(Appender::destroyAppender);
}
按照以上修改步骤之后,重新编译更新下库文件以后再看已经没有了内存泄露问题,问题得到解决。