昨天对已完成的项目进行测试时,使用top命令监控程序,发现程序的运行过程中内存增长的很快,因此判断程序中出现了内存泄漏问题。
监测进程使用过程中资源使用情况的方式
ps -el | grep xxx #通过ps查询xxx进程的pid top -p pid #通过top指令查看进程运行过程中的CPU、内存使用情况
由于本项目公司近几年一直以来都在维护,本人仅参与了其中一部分业务的开发,因此通过从微观层面解析每个子业务流程来排查内存泄漏的难度很大,无法在短时间内完成,而且内存泄漏出现在不止一处地方,无法确认内存泄漏是否完全解决
内存泄漏的危害:
轻微的内存泄漏在短时间内无法造成影响,但当程序运行一段时间后,“水滴石穿”的效应终将导致内存溢出,程序崩溃。这对于植入到硬件设备中的嵌入式程序来说是一个极大的隐患。因此必须确保在项目上线之前所有的内存泄漏都被排查出来并处理。
解决思路:
1、首先想到的是以二分调试的思想,每次只执行从开始到结束的一部分流程,然后观察程序运行过程中内存是否会继续增长,从而逐步缩小出现内存泄漏的代码块范围。
1.1、该方案虽然可行,但是观察进程运行过程中是否出现内存泄漏非常耗时,而且细微的内存泄漏无法发觉:例如每次处理一组输入,存在一个结构体内存块忘记释放。此时的内存增加非常缓慢。
1.2、另一个缺陷则是,无法精确定位出现内存泄漏的位置,仍然需要从代码实现层面找出内存泄漏的位置
2、使用Valgrind工具排查程序中的内存泄漏
官方文档地址:https://valgrind.org/docs/download_docs.html
ubuntu20.04下安装方式
sudo apt install valgrind
3、在排查中使用的几个主要参数为:
--tool=Memcheck 指定工具为内存错误检查器
--leak-check=full 信息显示具体泄漏位置
--trace-children=yes 完全检查内存泄漏
4、运行
valgrind --tool=memcheck --leak-check=full --show-reachable=yes --trace-children=yes ./xxx
开始运行程序,构造合理的测试数据确保各业务分支都被执行到,结束程序时,valgrind会打印相应的内存检查信息
definitely 由局部变量指向的内存,如果不释放为肯定丢失,
indirectly 由此指针而引起的后续内存泄露,为间接丢失.
possible lost 是全局申请的内存未释放,由于全局变量只会被申请一次内存,因此不必担心引发内存泄漏,在进程结束时自动释放。
根据打印信息可以发现在gtaoidcore.cpp:165处存在一个内存申请但未被释放引发了内存泄漏,排查完毕