c/c++开发内存泄漏问题解决——valgrind实战

c/c++开发内存泄漏问题解决——valgrind实战

背景介绍:本人开发的一款http服务端程序,通过http协议和后端通信接受任务,任务需要调用ffmpeg的api完成视频截取,任务采用多线程的形式,需要承受上千路的高并发场景,在压力测试的时候发现每次测试,程序使用的内存就会变多,由于是多线程场景,叠加很多内存是调用第三方库申请的,无法直接排查,所以学习使用valgrind完成内存检查。
valgrind背景知识:
官网地址:https://valgrind.org/

一、环境准备

本人使用的环境是windows11系统下的wsl2的ubutun22.04环境,此环境的ubutun已经非常接近完整的ubutun桌面环境了,可以安装图形化桌面(本项目未使用),也可以使用带图形渲染的程序,例如谷歌浏览器,本项目使用了massif-visualizer

二、内存泄漏检查

普通的内存泄漏检查可以使用valgrind 的memcheck 工具
安装过程如下:(安装推荐使用命令行,最简单方便)
sudo apt update
sudo apt install valgrind
使用例子如下:
https://blog.youkuaiyun.com/u012770580/article/details/103065995
实操过程:
valgrind --leak-check=full ./my_program
在运行的时候程序log会发出提示哪些地方有泄漏风险,检查代码解决相关问题

三、代码检查

(项目比较小,比较方便这样检查)通过搜索工具找到所有显式申请内存的地方,本项目主要是new了新类,尽量将new转换为智能指针,在申请和释放内存的地方增加打印、在类的初始化和析构函数内增加打印,追踪没次循环的打印是否对应,找到不对应的地方,进行改进。

四、内存堆积检查

内存申请了,但是没释放,并不会被判断成内存泄漏,但是程序占用内存会线性增加,这时候就需要massif工具。
安装:
sudo apt install valgrind-massif-visualizer
sudo apt install massif-visualizer
使用教程:
massif官网地址:https://valgrind.org/docs/manual/ms-manual.html#ms-manual.theoutputgraph
massif翻译:https://blog.youkuaiyun.com/weixin_43402206/article/details/127850215
更多参数:https://blog.youkuaiyun.com/fengbingchun/article/details/50196189

使用:

valgrind --tool=massif --max-threads=80000 ./my_program
在程序正常退出的时候会生成相关分析文件和log:massif.out.1138426 后面的数字是进程号
文件分析:
1、ms_print massif.out.1138426 将分析结果转换为txt,进行详细查看
2、massif-visualizer massif.out.1138426将文件可视化分析
在这里插入图片描述
1表示申请内存常用的函数,不同颜色表示不同的申请来源
点击2,2高亮连带3对应区域也高亮,一点点的展开就能知道内存堆积的元凶代码在哪里。
我这边是ffmpeg的函数:avcodec_open2导致的,找到释放内存的正确方法,修改逻辑各种失败的情况下如何释放内存,当一切改进完毕后图像是这样的:
在这里插入图片描述
辅助检查:
ps -a 查看被测程序的pid
watch -n 1 “ps -p 3967 -o rss= | awk ‘{print $1/1024}’” 查看具体某个程序的内存占用情况,多次循环后内存使用没明显增加,表示内存已经正确释放
在这里插入图片描述

五、稳定性提升

使用gdb工具打开程序,在崩溃时记录崩溃点,使用调用栈查看崩溃点,修改代码增强多线程的处理逻辑。
笔记:http1.1服务中处理完当前代码后不会立即断开连接,而是会继续保持连接,同时占用一个socket,超时时间内均会保持连接,除非客户端发出断开连接指令或者请求里表明不需要长连接
这导致我在本机压测的时候socket迅速耗尽,服务器的socket数量很多,不存在此问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值