内存泄露问题的跟进方法之一

程序dbstore连接cm时发送1万条左右的数据就会报”连接不上cm“的错误,此时重启dbstore,仍可继续发送,发送一端时间之后又会报这种错误

方法:看代码找错误日志,看看代码中的哪条错误信息出现在了代码中,据此找到问题

结果:代码中有些错误判断时没有打印错误日志,这种多是malloc的代码

 

到底是哪个分配失败了呢?

方法2:使gdb调试,看看程序失败在哪里

1、从日志中提取出错的行,b xxx.cpp:1383 设置断点后,c 继续;info locals后查看变量信息,发现val_buf值为0,说明分配失败,此时iRetVal值为-15,

2、在代码中查看该值对应的而错误确实为InitBuffError,证明分配内存失败

 

为什么是分配内存失败了呢?正常是不会失败的啊

方法3:这才想起来检查虚拟内存大小

pgrep xxx找到今晨号后ps -aux 找到虚拟内存大小

通过监控平台发现dbstore占用的虚拟内存达到11g之多显然内存泄露了


valgrind为什么没检查出来?

代码哪里泄露了?

看了下,

char * keys_buf = NULL;....
    try
    {
        char * keys_buf = (char *)malloc( keys_buf_size );
        if(NULL == keys_buf)
        {
            iRetVal = DbStoreErrorCode::ERR_InitBuffError;
            throw "error";
        }

。。}catch (...)
        {
            ul_writelog(UL_LOG_FATAL, "exception occurs @%s:%d", __FILE__, __LINE__);
            if (NULL != keys_buf)
            {
                free(keys_buf);
            }
         。。。

}//end catch

if (NULL != keys_buf)
        {
            free(keys_buf);
        }...


你发现了吗?

是的,try里面定义的变量catch里面看不到,try外面也看不到,所以try里面分配的内存没有释放,导致有内存泄露!!

总结:

1、测程序除了valgrind检查外,一定记得看虚拟内存的大小是否增加很厉害~~~

2、日志很重要,gdb很强大

3、看代码codereivew注意变量作用域

posted @ 2012-07-10 20:29  mangu_uu  阅读(464)  评论(0编辑  收藏  举报