内存泄露检测工具Valgrind

 

内存泄露简介

什么是内存泄漏

  内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因,程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。
  内存泄漏缺陷具有隐蔽性、积累性的特征,比其他内存非法访问错误更难检测。因为内存泄漏的产生原因是内存块未被释放,属于遗漏型缺陷而不是过错型缺陷。此外,内存泄漏通常不会直接产生可观察的错误症状,而是逐渐积累,降低系统整体性能,极端的情况下可能使系统崩溃。

内存泄露产生的方式

以产生的方式来分类,内存泄漏可以分为四类:

  • 常发性会内存泄漏:发生内存泄漏的代码会被多次执行到,每次被执行时都导致一块内存泄漏。
  • 偶发性内存泄漏:发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。所以测试环境和测试方法对检测内存泄漏至关重要。
  • 一次性内存泄漏:发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块且仅有一块内存发生泄漏。
  • 隐式内存泄漏:程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏。从用户使用程序的角度来看,内存泄漏本身不会产生什么危害,作为一般的用户,根本感觉不到内存泄漏的存在。真正有危害的是内存泄漏的堆积,这会最终耗尽系统所有的内存。从这个角度来说,一次性内存泄漏并没有什么危害,因为它不会堆积,而隐式内存泄漏危害性则非常大,因为较之于常发性和偶发性内存泄漏它更难被检测到。

Valgrind

简介

  Valgrind具是一个用于调试和分析Linux程序的GPL系统。使用Valgrind的工套件,您可以自动检测许多内存管理和线程错误,使程序更稳定。还可以执行详细的分析以帮助加速程序的执行。
  Valgrind是Julian Seward的作品。Valgrind是运行在Linux上一套基于仿真技术的程序调试和分析工具,它包含一个内核,一个软件合成的CPU,和一系列的小工具。如下图所示:

安装

  CentOS安装:

# sudo yum install valgrind -y

  Ubuntu 安装:

# sudo apt install valgrind -y

示例程序

  给出一个简单示例malloc.c 。

#include<stdio.h>
#include<stdlib.h>
void fun()
{
int *x = malloc(10 * sizeof(int));
x[10] = 0;
}
int main()
{
int i = 99;
fun();
printf("i = %d\n",i);
return 0;
}

  以上代码存在两个问题:

  • 没有free掉申请的资源;
  • fun函数里面越界了,x[10]是非法的。

Memcheck

  是最常用的小工具,用来检测程序中出现的内存问题,所有对内存的读写都会被检测到,一切对malloc和free的调用都会被捕获,它能检测下列问题:

  • 对未初始化内存的使用;
  • 读/写释放后的内存块;
  • 读/写超出malloc分配的内存块;
  • 读/写不适当的栈中的内存块;
  • 内存泄漏,指向一块内存的指针永远丢失;
  • 不正确的malloc/free或new/delete匹配;
  • memcpy相关函数中的dst和src指针重叠;

  我们使用Memcheck小工具来检测存在的问题。
  编译:gcc -Wall -o malloc malloc.c
  检测:valgrind ./malloc
    --show-reachable=<yes|no> [default: no]
    --leak-check=full 查看更为详细信息

  其中,34496是程序运行时的进程号。
  Invalid write of size 4:表示非法写入(越界),下面是告诉我们错误发生的位置,在main中调用的fun函数。
  HEAP SUMMARY:说明了堆的情况,可以看到申请了40个字节,后面说有1个申请,0个被free。
  LEAK SUMMARY:也是说的堆的泄漏情况,明显丢失的有40个字节。
  如果main中的i未初始化,这里还会有一些其他的错误。

 

Callgrind

  和gprof 类似的分析工具,但它对程序的运行观察更细致入微,能给我们提供更多的信息。和gprof不同,它不需要在编译源代码时添加附加特殊选项,但加上调试选项是推荐的。
  Callgrind收集程序运行时的一些数据,建立函数调用关系图,还可以有选择的进行cache模拟。在运行结束时,它会把分析数据写入一个文件,callgrind_annotate可以把这个文件的内容转化成可读的形式。

  Callgrind可以帮助我们对程序的运行进行观察。

# valgrind --tool=callgrind ./malloc

  

  可以看到生成了一个文件callgrind.out.34755,同样34755为程序运行时的进程号。当callgrind运行你的程序时,还可以使用callgrind_control来观察程序的执行,而且不会干扰它的运行。
  显示程序的详细信息:

# callgrind_annotate callgrind.out.34755

  

Cachegrind

  Cache分析器,它模拟CPU中的一级缓存I1,DI和二级缓存,能够精确的指出程序中cache的丢失和命中。如果需要,它还能为我们提供cache丢失次数,内存引用次数,以及每行代码,每个函数,每个模块整个程序产生的指令数,这对优化程序有很大的帮助。  

# valgrind --tool=cachegrind ./mallo

Helgrind

  用来检测多线程程序中出现的竞争问题。Helgrind寻找内存中内对个线程访问,而又没有一贯加锁的区域。这些区域往往是线程之间失去同步的情况,而且会导致难以发掘的错误。
  Helgrind实现了名为“Eraser”的竞争检测算法,并做了进一步改进,减少了报告错误的次数。不过Helgrinf仍然处于实验阶段。

Massif

  堆栈分析器,它能测量程序在堆栈中使用了多少内存,告诉我们堆块,堆管理块和栈的大小。Massif能帮助我们减少内存的使用,在代用虚拟内存的现代系统中,它还能加速我们程序的运行,减少程序停留在交换区中的几率。

  此外,lackey和nulgrind也会提供。Lackey是小型工具,很少用到;Nulgrind只是为开发者展示如何创建一个工具。

参考

  Linux下几款C++程序中的内存泄露检查工具
    https://blog.csdn.net/gatieme/article/details/51959654
  Linux下检测内存泄露的工具 valgrind
    https://cloud.tencent.com/developer/article/1075945
  Valgrind调试
    http://www.voidcn.com/article/p-xyrqgaum-yq.html

内存泄漏(Memory Leak)的更多相关文章

  1. 堆(heap)和栈(stack)、内存泄漏(memory leak)和内存溢出

    来源:http://blog.itpub.net/8797129/viewspace-693648/ 简单的可以理解为:heap:是由malloc之类函数分配的空间所在地.地址是由低向高增长的.sta ...

  2. 内存泄漏(Memory Leak)

    什么情况下会导致内存泄露(Memory Leak)? Android 的虚拟机是基于寄存器的Dalvik,它的最大堆大小一般是16M,有的机器为24M.因此我们所能利用 的内存空间是有限的.如果我们的 ...

  3. Android 内存管理 &Memory Leak & OOM 分析

    转载博客:http://blog.csdn.net/vshuang/article/details/39647167 1.Android 进程管理&内存 Android主要应用在嵌入式设备当中 ...

  4. 内存溢出(Oom)和内存泄露(Memory leak)

    1.概念 内存溢出(Oom):1.内存不够用:2.数据长度短的数据类型存储了一个数据长度较大的数据类型:3.一个结果 内存泄露(Memory leak):1.忘记释放已用内存,内存管理较为常见的现象: ...

  5. SQL Server 内存泄露(memory leak)——游标导致的内存问题

    原文:SQL Server 内存泄露(memory leak)--游标导致的内存问题 转自:http://blogs.msdn.com/b/apgcdsd/archive/2011/07/01/sql ...

  6. 内存泄漏 Memory Leaks 内存优化 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  7. malloc(50) 内存泄露 内存溢出 memory leak会最终会导致out of memory

    https://en.wikipedia.org/wiki/Memory_leak In computer science, a memory leak is a type of resource l ...

  8. 内存溢出(Memory Overflow)和内存泄露(Memory Leak)的区别

    内存泄漏指你用malloc或new申请了一块内存,但是没有通过free或delete将内存释放,导致这块内存一直处于占用状态 内存溢出指你申请了10个字节的空间,但是你在这个空间写入11或以上字节的数 ...

  9. python内存泄露memory leak排查记录

    问题描述 A服务,是一个检测MGR集群主节点是否发生变化的服务,使用python语言实现的. 针对每个集群,主线程会创建一个子线程,并由子线程去检测.子线程会频繁的创建和销毁. 上线以后,由于经常会有 ...

  10. 利用linux的mtrace命令定位内存泄露(Memory Leak)

    一谈到内存泄露, 多数程序猿都闻之色变. 没错, 内存泄露非常easy引入. 但非常难定位.  以你我的手机为例(如果不常常关机). 如果每天泄露一些内存, 那么開始的一个星期, 你会发现手机好好的. ...

随机推荐

  1. web api与mvc的区别

    MVC主要用来构建网站,既关心数据也关心页面展示,而Web API只关注数据 Web API支持格式协商,客户端可以通过Accept header通知服务器期望的格式 Web API支持Self Ho ...

  2. 完美转发(perfect forwarding)、universal reference、引用折叠(collasping)

    首先要分清: C++里的值只有两种值:左值.右值.—— 其本质应该是内存中存储的值/instance分两种:一种是持久的,一种是“短暂的” 也只有两种引用: 左值引用.右值引用. ——引用,就是这个内 ...

  3. Python中的函数(高级使用)

    一.将函数作为变量去使用 在Python中函数也是一种对象,是一种名为function的对象,所以可以将函数赋值给变量,类似整数.浮点数.列表.元组.字典赋值给变量. 我们编写如下程序: #codin ...

  4. 记一次CSS反爬

    目标网址:猫眼电影 主要流程 爬取每一个电影所对应的url 爬取具体电影所对应的源码 解析源码,并下载所对应的字体 使用 fontTools 绘制所对应的数字 运用机器学习的方法识别对应的数字 在源码 ...

  5. Linux实用指令(5)

    指定运行级别(系统的制定级别配置文件/etc/inittab): 0:关机 1:单用户(单用户级别root登录不需要密码,进入之后重新设置密码) 2:多用户无网络服务 3:多用户有网络服务 4:系统未 ...

  6. electron项目中使用js web worker时,new worker(path)路径问题

    如题,在new worker时需要传入js文件路径,可是在electron环境中使用出现问.同目录下,recorder.jsworker.js recorder.js中调用 var path = '. ...

  7. Linux从入门到放弃、零基础入门Linux(第二篇):在虚拟机vmware中安装linux(一)超详细手把手教你安装centos分步图解

    一.Vmware vmware介绍:VMware,Inc. (Virtual Machine ware)是一个“虚拟PC”软件公司,提供服务器.桌面虚拟化的解决方案.其虚拟化平台的产品包括播放器:它能 ...

  8. C# Net 比较2个字符串的相似度(使用余弦相似度)

    C# Net 比较2个字符串的相似度(使用余弦相似度) 复制代码使用: /// <summary> /// 比较2个字符串的相似度(使用余弦相似度) /// </summary> ...

  9. itextpdf5生成document生成pdf的简单dome

    package dbzx.pdf; import java.io.FileNotFoundException; import java.io.FileOutputStream; import org. ...

  10. Linux下安装Nexus-3.15私服

    1.切换到root用户 创建nexus用户:useradd nexus 设置nexus用户密码:passwd nexus 2.创建文件夹并进入该目录 linux中,软件包一般放在opt目录下,安装时, ...