背景: 这熟悉的线条. 请求量没啥波动, 不用怀疑, 就是内存泄露了.
方案一 Valgrind
Valgrind可以用来检测是否有非法使用内存的问题, 如: 访问未初始化的内存,访问数组越界, 忘记释放动态内存的问题;
首先需要定位是哪个进程的内存泄露. 使用top命令, 然后shift+m按照内存排序, 找到%MEM最高(或上升最快的)进程(RES). 测试机可复现, 后续步骤测试机完成.
2.安装valgrind包. 可以直接在编译程序时, 加上-g选项. 如下图为例:
gcc -g -o test test.cpp
valgrind --tool=memcheck --leak-check=full ./test
由于我们的是spp框架(开源github可看源码): 所以就手动启动的proxy进程.
3.使用valgrind包启动一个worker进程. 进入到服务的bin目录下执行:
../../valgrind-1.0/bin/valgrind --tool=memcheck --leak-check=full --log-file=valgrind.log ./spp_xxx_worker ../etc/spp_worker1.xml
启动报错:
valgrind: failed to start tool ‘memcheck’ for platform ‘amd64-linux’: No such file or directory
执行命令:
export VALGRIND_LIB=/usr/local/services/valgrind-1.0/lib/valgrind/
- 发送请求. 待返回结果后, 调valgrind的进程号, 执行:
kill -10 pid
- kill之后查看valgrind.log (还以上图test.cpp为例)
左边类似行号的数字(22939)表示的是ProcessID; 上面的HEAP SUMMARY, 会显示valgrind发现的内存问题, 堆栈信息, 和具体的代码行数. 最下面的LEAK SUMMARY是个问题汇总. 不过在实际执行中, 因为我们会跑全量的请求. 所以不会这么整齐, 不过搜索关键字, 还是可以看到有用的信息的.
方案二 core文件
1.这个也是在网上搜的一个方法, 首先和思路一样, 都是要寻找升的快的进程. 通过top命令;
2.定位内存泄露的地址范围; 通过pmap -x ${pid} 查看内存情况. 这里我通过spp的配置, 只起一个worker进程, 也就是单线程排查. 通过pmap -x ${pid} 的结果, 可以找到占用多的块.
3.导出内存中的内容. gcore ${pid} ; 通过gdb关联的spp_worker 和coredump文件.文章来源:https://www.toymoban.com/news/detail-533625.html
gdb spp_worker(xxx) core.2005(pid)
info proc mappings
dump binary memory result.bin ${start addr} ${start addr} (eg:dump其中一部分即可)
vim result.bin (使用 :%!xxd 的方式查看内容)
理论上在这个文件中, 可以到可读的, 有意义的字段, 再根据代码去定位.文章来源地址https://www.toymoban.com/news/detail-533625.html
到了这里,关于C++内存泄露排查的一个案例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!