C++ 内存占用分析(内存泄漏)

文章目录

  • 前言
  • 一、什么是内存泄漏
  • 二、如何检测内存泄漏
    • 1、内存占用变化排查法
    • 2、valgrind定位法
    • 3、mtrace定位法
  • 参考资料

前言

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

一、什么是内存泄漏

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

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

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

二、如何检测内存泄漏

1、内存占用变化排查法

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

2、valgrind定位法

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

sudo apt install valgrind
valgrind ./main

参考链接:valgrind排查内存泄露

3、mtrace定位法

#include 
 
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++程序内存泄漏跟踪总结

你可能感兴趣的:(Linux,C/C++编程,开发语言)