Ubuntu20.04使用valgrind进程内存分析
一、前言
Valgrind是linux环境下开发应用程序时用于内存调试和性能分析的工具集,其中Memcheck工具可以用来检查C/C++程序中的内存操作错误。本文列举了几种常见的内存操作错误以及Memcheck工具的检测结果,其中包括以下几种类型:
- 使用未初始化的内存
- 内存读写越界
- 内存覆盖
- 读写已经释放的内存
- 内存泄露
文章内容主要分为四个部分,valgrind工具的下载与安装、实例分析、常用选项说明和suppressing errors的设置。通过这四部分的学习,读者可以基本掌握valgrind工具的内存调试方法。
二、下载与安装
在官网https://valgrind.org/downloads/上下载软件,目前最新版本是Valgrind 3.20.0。
然后按照下面的命令解压安装
1 2 3 4 5 6 7 8 9 | sudo apt-get install automake sudo apt-get install autoconf tar -jxvf valgrind-3.20.0. tar .bz2 cd valgrind-3.20.0 . /autogen .sh . /configure --prefix= /usr/local/valgrind // 根据自己的需要设置安装目录 make -j4 sudo make install |
注意:需要把valgrind的bin目录路径添加到环境变量PATH中,打开~/.bashrc文件,在最后一行加入
1 | PATH=${PATH}: /usr/local/valgrind/bin |
然后刷新环境变量:
1 | source ~/.bashrc |
因为不设置环境变量,你会找不到valgrind指令:
三、valgrind实例分析
推荐阅读官方文档:https://valgrind.org/docs/manual/valgrind_manual.pdf
3.1 生成可执行文件
在makefile中增加调试模式的配置,由于在debug状态下推理出的问题多于release状态下,因此最好切换到debug进行valgrind检测。或者gcc在编译源程序时需要加上-g参数。
3.2 启动被测试的可执行文件
valgrind 命令的基本格式为:valgrind [base option] --tool=<tool name> [tool option] your-program [program options]
通过valgrind启动可执行文件的方式如下(在当前目录情况下):
1 | valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all --track-origins= yes - v --log- file = "memcheck.txt" . /executable_file |
注意:这里我将所有信息保存在了日志文件中,以便分析!
3.3 错误信息分析
Valgrind工具会在可执行文件执行过程中顺序输出检测到的错误信息。下面分段介绍可执行文件的测试结果,其中双斜线开头的为注释信息。
工具相关信息:
1 2 3 4 5 | ==248067== Memcheck, a memory error detector ==248067== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al. ==248067== Using Valgrind-3.20.0-5147d671e4-20221024 and LibVEX; rerun with -h for copyright info ==248067== Command: . /analysis_service ==248067== Parent PID: 222425 |
第一个内存错误:使用了未初始化的变量
四、Linux下如何确定内存泄露(补充)
在 Linux 环境的 C/C++ 开发中,当每次只是发生几个字节的内存泄露时,可以写一段测试内存泄露的代码来确认。而当代码中发生可见的大量的内存泄露问题时,可以使用 shell 命令来确认:
- ps 命令
- top 命令
- free 命令
- cat /proc/meminfo 或 cat /proc/$pid/status 命令
4.1 ps 命令
ps 命令用来列出系统中当前正在运行的那些进程,列出的是当前那些进程的快照,就是执行 ps 命令的那个时刻的那些进程。确定有哪些进程正在运行和运行的状态、进程是否结束、进程有没有僵死、哪些进程占用了过多的资源等。
ps 命令为我们提供了进程的一次性的查看,它所提供的查看结果并不动态连续的;如果想对进程实时监控,应该用 top 命令。
常用的命令如:
1 2 3 4 5 6 7 8 9 10 11 | ps -ef | grep 进程关键字 // 查看指定进程的信息 ps -aux // 列出当前内存中的所有进程 ps aux -- sort =%mem(或者 ps aux -- sort %mem) // 按照内存占用率的升序排序 ps aux -- sort =-%mem (或者 ps aux -- sort -%mem) // 按照内存占用率降序排序 ps aux | grep -e test // 打印含义 test 关键字的进程 ps -aux | grep -E "test|PID" // 打印 包含 test 关键字的进程信息 |
4.2 top 命令
top 命令是 Linux 下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows 的任务管理器。通常用来观察 CPU 或 内存的占用情况。
top 命令使用如下:
1 2 | top -d -3 //3s 显示一次 top -p 1921 // 显示进程号为 1921 的进程的信息 |
4.3 free 命令
free 命令可以显示当前系统内存使用情况,主要用于确定设备是否存在内存泄漏。free 命令中的信息都来自于 /proc/meminfo 文件。
默认情况下,即在没有选项的情况下,free 命令显示内存的使用信息。默认按照 k(b) 的计数单位统计。
free 命令使用如下:
1 | free -s 3:表示每隔 3 秒打印一次内存信息 |
注意:可以通过在设备启动和运行一段时间后,使用 free 命令查看 已使用内存(used) 的大小并进行对比,如果运行一段时间后 used内存 有很明显的增大,那很有可能是存在内存泄漏。
4.4 cat /proc/meminfo 或 cat /proc/$pid/status 命令
1 2 3 | cat /proc/meminfo // 用来查看 Linux 系统的内存使用情况。 cat /proc/ $pid /status // 用来查看某个进程的内存使用信息。 |
查看 RAM 使用情况最简单的方法是通过 /proc/meminfo。这个动态更新的虚拟文件实际上是许多其他内存相关工具 (如 free / ps / top 命令) 等的组合显示。
注意:这个文件显示的单位是 kB 而不是 KB,1kB = 1000B,但是实际上应该是KB,1KB=1024B。这个显示是不精确的,是一个已知的没有被更正的历史遗留问题。因为很多程序依赖这个文件查看内存使用的是kB字符
如上所示,解释一下重要字段如下:
- MemTotal: 应用可以使用的内存总数
- MemFree: 当前空闲的内存数目
- MemAvailable: 可用内存(MemFree + 可回收的内存),系统中有些内存虽然已被使用,但是可以回收,如cache、buffer、slab都有一部分可以回收。
- Buffers: 用来给文件做缓存大小
其他暂不做解释。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了