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);
    }

按照以上修改步骤之后,重新编译更新下库文件以后再看已经没有了内存泄露问题,问题得到解决。

posted @ 2015-01-08 14:48  KAME  阅读(1234)  评论(1编辑  收藏  举报