内存泄露问题的跟进方法之一
程序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注意变量作用域