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

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

  • 相关阅读:
    项目
    Cache Code
    是什么限制了我们面向对象
    程序设计语言本质
    不要迷失在技术的海洋中
    程序是给自己看的还是给别人看的
    程序员的春天
    新手如何学习一门新的语言
    无废话C#设计模式之二十:Mediator
    (原创)代码分析-DataGrid实现增删(带提示)改和分页
  • 原文地址:https://www.cnblogs.com/sanghg/p/4210947.html
Copyright © 2020-2023  润新知