关于IOCP内存泄漏查找思路和结论
IOCP问题解决思考流程
从IOCP服务器压力测试中,出现服务器死机蓝屏,服务器程序重启。引发对问题的分析和解决
服务器涉及技术
对服务器设计技术的整理,有助于更快定位内存泄漏的位置,更模块化的分析服务器,有助于完善整个框架:
- IOCP 完成端口框架 ,C/S模式网络服务器端,充分利用Windows内核来进行I/O的调度,支持高并发数据通信处理;
- JSON数据格式 在数据格式交互上使用rapidjson库,来进行数据格式封装;
- mysql数据库 使用mysql来进行数据存储;
- VS快照内存分析 使用VS在debug下,对内存使用进行分析;
IOCP 完成端口框架
1.对IOCP对象的调用,销毁,消息机制进行深度学习
参考文献:IOCP模型与网络编程.
参考文献:完成端口(CompletionPort)详解.
参考文献: IOCP完成端口资料整理.
对 PER_SOCKET_CONTEXT 对象的增删进行分析
对 memcpy()复制的越界风险分析
对logger类log记录操作多次写入的越界风险分析
总结:在单个客户端长连接连续收发的压力测试下,系统上不会进行大规模内存创建操作(new或malloc),此次问题不在此处,后续若有问题,再行与君分享。
JSON数据格式
使用rapidjson库,可以分析出在document.Parse()中有碎片化内存申请,在进行隔离分析后,此次泄漏不在此处,但此类在大数据量测试下有泄漏风险,值得深入学习分析。
mysql数据库
在对数据库进行隔离中发现,出现了内存泄漏,原因在于MYSQL_RES *res 没有进行释放,现附代码如下:
int rc = mysql_real_query(pSqlCon, sql.c_str(), sql.length());
MYSQL_RES *res = mysql_store_result(pSqlCon);//将结果保存在res结构体中
int numrows = mysql_num_rows(res); /* 查找查询结果的行数 */
MYSQL_ROW row = mysql_fetch_row(res);
if (numrows != 1 && row != nullptr && *row != nullptr)
{
mysql_free_result(res);
return;
}
if (row == nullptr || *row == nullptr)
{
mysql_free_result(res);
return;
}
else
{
//对row中数据进行操作
}
mysql_free_result(res);//对结果保存结构体进行释放
内存泄漏在于没有调用mysql_free_result()进行数据库结果释放
参考文献:MySQL在C++中使用后务必释放 result,否则会造成内存泄露.
VS快照内存分析
参考文献:【VS】使用vs2017自带的诊断工具(Diagnostic Tools)诊断程序的内存问题.
总结
分析结果
内存泄漏在于没有调用mysql_free_result()进行数据库结果释放,具体代码查看详细说明mysql分析。
总结
对与内存泄漏,是一个非常无序的问题,尽量耐心和分功能部分分析,才能定位到具体的代码位置,
最后祝愿所有程序没有内存泄漏。