Ubuntu20.04使用valgrind进程内存分析

 一、前言

Valgrind是linux环境下开发应用程序时用于内存调试和性能分析的工具集,其中Memcheck工具可以用来检查C/C++程序中的内存操作错误。本文列举了几种常见的内存操作错误以及Memcheck工具的检测结果,其中包括以下几种类型:

  • 使用未初始化的内存
  • 内存读写越界
  • 内存覆盖
  • 读写已经释放的内存
  • 内存泄露

文章内容主要分为四个部分,valgrind工具的下载与安装、实例分析、常用选项说明和suppressing errors的设置。通过这四部分的学习,读者可以基本掌握valgrind工具的内存调试方法。

 

二、下载与安装

在官网https://valgrind.org/downloads/上下载软件,目前最新版本是Valgrind 3.20.0。

然后按照下面的命令解压安装

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文件,在最后一行加入

PATH=${PATH}:/usr/local/valgrind/bin   

然后刷新环境变量:

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启动可执行文件的方式如下(在当前目录情况下): 

valgrind --tool=memcheck  --leak-check=full --show-leak-kinds=all --track-origins=yes -v --log-file="memcheck.txt" ./executable_file  

注意:这里我将所有信息保存在了日志文件中,以便分析!

  

3.3 错误信息分析

Valgrind工具会在可执行文件执行过程中顺序输出检测到的错误信息。下面分段介绍可执行文件的测试结果,其中双斜线开头的为注释信息。

工具相关信息:

==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 命令。

常用的命令如:

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 命令使用如下:

top -d -3     //3s 显示一次
top -p 1921 //显示进程号为 1921 的进程的信息

 

4.3 free 命令

free 命令可以显示当前系统内存使用情况,主要用于确定设备是否存在内存泄漏。free 命令中的信息都来自于 /proc/meminfo 文件。

默认情况下,即在没有选项的情况下,free 命令显示内存的使用信息。默认按照 k(b) 的计数单位统计。

free 命令使用如下:

free -s 3:表示每隔 3 秒打印一次内存信息

注意:可以通过在设备启动和运行一段时间后,使用 free 命令查看 已使用内存(used) 的大小并进行对比,如果运行一段时间后 used内存 有很明显的增大,那很有可能是存在内存泄漏。  

 

4.4 cat /proc/meminfo 或 cat /proc/$pid/status 命令

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: 用来给文件做缓存大小

其他暂不做解释。

 

  

  

 

 

  

posted @ 2022-12-08 14:38  小金乌会发光-Z&M  阅读(1372)  评论(0编辑  收藏  举报