内存泄漏分析

本文介绍了内存泄漏的概念,以及在C++程序中如何通过内存占用变化、valgrind工具和mtrace定位法来检测内存泄漏。提到了野指针和内存碎片的影响,以及如何通过监控内存使用情况和分析工具进行问题诊断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

内存占用分析是一个比较庞大的话题,在C++程序中,进程的内存持续上涨,有可能是正常的内存占用,有可能是内存碎片,还有可能是内存泄漏。这里我们先来介绍一下内存泄漏。

一、什么是内存泄漏

在实际的 C++ 开发中,我们经常会遇到诸如程序运行中突然崩溃、程序运行所用内存越来越多最终不得不重启等问题,这些问题往往都是内存资源管理不当导致的。比如:

  • 有些内存资源已经被释放,但指向它的指针并没有改变指向(成为了野指针),并且后续还在使用;
  • 有些内存资源已经被释放,后期又试图再释放一次(重复释放同一块内存会导致程序运行崩溃);
  • 没有及时释放不再使用的内存资源,造成内存泄漏,程序占用的内存资源越来越多。

参考链接:C/C++什么是内存泄露,内存泄露如何避免?

二、如何检测内存泄漏

1、内存占用变化排查法

内存泄漏一般不会造成程序崩溃,所以比较隐晦,但是发现内存泄露的方法也很简单,就是让程序运行一段时间,然后查看内存先后变化,通过任务管理器(windows)或者top(unix/linux)来监控某个进程的内存变化是比较方便的,有些程序的内存泄露比较小,但是发现它的内存泄露也都是时间问题。这里列出一个内存泄漏的程序的内存变化时间图,可以看出其内存占用总体上是呈递增的
在这里插入图片描述
内存泄漏较大的情况下,机器cpu使用率飙升,cpu的wait百分比增加,通过top可以看到swap内存使用量不断增加,kswap进程不时出现在进程列表当中。
linux中可以通过watch -n1 "ps -o vsz -p <PID>",实时看到特定进程的内存使用量不断地增加

2、valgrind定位法

debian/ubuntu派系的linux下安装使用方法:

sudo apt install valgrind
valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all --undef-value-errors=no --log-file=log ./你的可执行文件名
  • –tool=memcheck:使用 memcheck 工具检测内存错误,包括使用未初始化的变量、读写越界等。
  • –leak-check=full:全面检测内存泄漏,不仅仅检测未释放的内存,还会检测处理时出现的一些问题。
  • –show-leak-kinds=all:显示所有的内存泄漏信息。
  • –undef-value-errors=no:不检查未定义的值错误。
  • –log-file=log:将日志信息输出到 log 文件中。

3、mtrace定位法

#include <mcheck.h>
 
int main(int argc, char **argv)
{
   setenv("MALLOC_TRACE","output",1);
 
   mtrace();
}

运行程序之后,在程序的当前目录下会生成output文件,然后使用命令获取堆栈信息:

mtrace [程序名] output > msg.txt

通过查看msg.txt文件,就可以找到内存泄漏的地方、大小,如:

Memory not freed:
-----------------
           Address     Size     Caller
0x0000000001ed4760     0x18  at 0x7fface2c1780
0x0000000001ed47b0     0x18  at 0x7fface2c1780
0x0000000001ed59f0     0xb0  at 0x7fface2c1780
0x0000000001ed5ab0     0x18  at 0x7fface2c1780
0x0000000001ed5ad0     0x18  at 0x7fface2c1780
0x0000000001ed5af0     0x18  at 0x7fface2c1780

参考资料

  1. 内存泄漏(增长)火焰图
  2. C/C++ 程序分析内存的几种方法
  3. valgrind简介与使用
  4. c/c++程序内存泄漏跟踪总结
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值