概述

内存泄露(memory leak)指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况,在大型的、复杂的应用程序中,这时就出现了内存泄露。尽管优秀的编程实践可以确保最少的泄露,但是根据经验,当使用大量的函数对相同的内存块进行处理时,很可能会出现内存泄露。

内存泄露可以分为以下几类:
  1. 常发性内存泄漏。发生内存泄露的代码会被多次执行到,每次被执行的时候都会导致一块内存泄露。

2. 偶发性内存泄露。发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。所以测试环境和测试方法对检测内存泄露至关重要。

3.一次性内存泄露。发生内存泄露的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块且仅一块内存发生泄露。比如,在一个Singleton类的构造函数中分配内存,在析构函数中却没有释放该内存。而Singleton类只存在一个实例,所以内存泄露只会发生一次。

4.隐式内存泄露。程序在运行过程中不停地分配内存,但是知道结束的时候才释放内存。严格的说这里并没有发生内存泄露,因为最终程序释放了所有申请的内存,但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致耗尽系统的所有内存。所以,我们称这类内存泄露为隐式内存泄漏。

内存泄漏检测工具

现在有很多方法来检测内存泄露,以下列举了linux常用的内存泄露检测工具。

1、mtrace

应用环境: Linux GLIBC

编程语言: C

使用方法: 包含头文件mcheck.h,定义环境变量MALLOC_TRACE为输出文件名,程序开始时调用mtrace()即可。

结果输出:用户指定的文件

设计思路:为malloc,realloc,free函数添加钩子函数,记录每一对malloc-free的执行

优缺点:只能检查使用malloc/realloc/free造成的内存泄露

如何获取:GLIBC自带,可直接使用

2、memwatch

  应用环境:Linux

  编程语言:C

使用方法: 加入memwatch.h,编译时加上-DMEMWATCH -DMW_STDIO及memwatch.c

结果输出:输出文件名称为memwatch.log,在程序执行期间,错误提示都会显示在stdout上

设计思路:将malloc/realloc/calloc/strdup/free等重定义为mwMalloc(sz, __FILE__, __LINE__)等,内部维护一个操作链表

优缺点:能检测双重释放(double-free)、错误释放(erroneous free)、内存泄露(unfreed memory)、溢出(Overflow)、下溢(underflow)等等

如何获取:http://memwatch.sourceforge.net/

3、valgrind

应用环境:Linux

  编程语言:C/C++

使用方法:编译时加上-g选项,如gcc -g filename.c -o filename,使用如下检测内存使用情况:

结果输出: #valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ./filename,就会看到内存使用报告

设计思路:根据软件的内存操作维护一个有效地址空间表和无效地址空间表(进程的地址空间)

优缺点:能够检测:

  • 使用未初始化的内存(Use of uninitialised memory)
  • 使用已经释放了的内存(Reading/writing memory after it has been free'd)
  • 使用超过malloc分配的内存空间(Reading/Writing off the end of malloc'd blocks)
  • 对堆栈的非法访问(Reading/writing inappropriate areas on the stack)
  • 申请的空间是否有释放(Memory leaks -- where pointers to malloc'd blocks are lost forever)
  • malloc/free/new/delete申请和释放内存的匹配(Mismatched use of malloc/new/new[] vs free/delete/delete[])
  • src和dst的重叠(Overlapping src and dst pointers in memcpy() and related functions)
  • 重复free

如何获取: http://valgrind.org/

4、debug_new

应用环境:Linux/Windows

  编程语言:C++

  使用方法: 包含头文件debug_new.h,链接debug_new.cpp

结果输出: 控制台console

设计思路:通过重载new和delete操作符来捕获内存申请/释放请求,并在程序内部维护一个全局静态变量的哈希链表。在new操作符中,不仅仅分配用户所要求的的内存,而是在为每次分配的内存都添加一个头部,存储着此次分配的位置信息和链表指针,new返回的是分配的这块内存加上头部偏移后的值,而在之前已经将此返回值作了HASH计算并添加到HASH链表中了。delete的时候先根据要释放的指针地址做HASH计算,然后再遍历数组HASH值处的链表进行查找,如果找到则将该节点移除,未找到就abort。这样在程序结束之后,通过检查此数组中是否还有未释放的内存块来确定是否有内存泄露。

优缺点:跨平台,仅用于C++程序。

如何获取:http://www.ibm.com/developerworks/cn/linux/l-mleak2/index.html

总结

以上的这些分析工具,所使用的方法大致分为以下几种:

1、注册内存分配/释放钩子函数(hook)。在Linux下可以malloc_hook,free_hook等5个钩子函数,在Windows下可以注册————CrtSetAllocHook钩子函数,这样在分配内存的时候就可以捕获这一请求并加以处理。Visual Leak Detecter和mtrace使用此方式。

2、使用宏定义替换。将用户代码中的malloc,free替换为宏定义的mwMalloc(sz, __FILE__, __LINE__)等自定义函数,从而跟踪内存情趣,memwatch即使用此方式。

3、操作符重载。此方法仅用于C++语言中,通过重载new、delete操作符来实现跟踪内存请求,重载后的操作符类似于钩子函数意义。debug_new采用此方式。

这些工具的输出方式也分以下几种:

1、普通环境下一般输出到调试窗口中,很多软件本身就提供了一个理想的输出场所,并且GUI应用程序输出到标准输出时不可见的。Visual Leak Detecter采用此法。

2、输出到标准输出或标准错误输出:控制台应用程序可以输出到屏幕,如memwatch, valgrind, debug_new都是采用这种方法。

3、输出到日志文件:将结果输出到用户指定或默认的日志文件中,如mtrace和memwatch

此外,这些工具的内存检测方式无非也分为两种:

1、维护一个内存操作链表,当有内存申请操作时,将其加入此链表中,当有释放操作时,从申请操作从链表中移除。如果到程序结束后此链表中还有内容,说明有内存泄露了;如果要释放的内存操作没有在链表中找到对应操作,则说明是释放了多次。使用此方法的有内置的调试工具,Visual Leak Detecter,mtrace,memwatch,debug_new。

2、模拟进程的地址空间。仿照操作系统对进程内存操作的处理,在用户态下维护一个地址空间映射,此方法要求对进程地址空间的处理有较深的理解,因为Windows的进程地址空间分布不是开源的,所有模拟起来很困难,因此只支持Linux。采用此方法的是valgrind。

Linux下内存泄露工具相关推荐

  1. Linux下内存检测工具:asan

    Linux下内存检测工具:asan ASAN(Address-Sanitizier)早先是LLVM中的特性,后被加入GCC 4.8,在GCC 4.9后加入对ARM平台的支持.因此GCC 4.8以上版本 ...

  2. linux下内存性能测试工具STREAM

    Linux下内存性能测试 简介 下载并解压 编译 运行 运行结果 结果分析 简介 Stream测试是内存测试中业界公认的内存带宽性能测试基准工具,stream由Virginia University提 ...

  3. Linux下内存泄露排查讨论

    作为c的程序员,最常见的就是排查内存泄漏,不过我们一般的内存泄漏是针对特定的程序去排查,相对来说比较容易,但是如果是维护人员,不知道哪个程序有内存泄漏,甚至是应用程序的内存泄漏,还是内核的内存泄漏都不 ...

  4. linux注入内存泄露,Linux 内存泄露小结

    本文仅限记录自己的一次 内存泄露追踪小记. 可能并不十分适用与大家的情况.而且方法也并不是很smart.仅做记录,能提供个思路更好. 一. 要问调试程序遇到什么问题最头疼, 内存泄露肯定能排在前几名里 ...

  5. eclipse内存设置Linux,Eclipse CDT Linux下内存分析 补记

    常用工具汇总 常用的内存分析工具 PurifyPlus 不支持常用的Linux 64系统[Ubuntu redhat],悲剧 Valgrind简介 Memcheck Memcheck 工具主要检查下面 ...

  6. arm linux下交叉编译valgrind工具进行内存泄露检测和性能分析

    C/C++等底层语言在提供强大功能及性能的同时,其灵活的内存访问也带来了各种纠结的问题.如果crash的地方正是内存使用错误的地方,说明你人品好.如果crash的地方内存明显不是consistent的 ...

  7. Linux环境下内存泄露检测

    linux下内存泄漏检测工具valgrind 该工具可以检测下列与内存相关的问题 : 未释放内存的使用 对释放后内存的读/写 对已分配内存块尾部的读/写 内存泄露 不匹配的使用malloc/new/n ...

  8. Linux下内存泄漏定位方法

    Linux下内存泄漏可分为用户空间的内存泄漏和内核空间的内存泄漏. 用户空间内存泄漏的查找方法: 第一步,查找内存泄漏的应用程序. 首先,写一个简单的内存泄漏程序(每秒钟泄漏4MB)umemleak. ...

  9. Linux下C++开发工具介绍

    概述     就C++开发工具而言,与Windows下微软(VC, VS2005等)一统天下相比,Linux/Unix下C++开发,可谓五花八门,各式各样.Emacs, vi, eclipse, an ...

最新文章

  1. libcurl远程获取文件大小源码
  2. VM虚拟机报错:An error occurred during the file system check.
  3. MPB:中科院生态环境中心邓晔组-环境样本中原核生物的总量测定
  4. Spring Hiernate整合
  5. python程序设计——函数设计与调用
  6. SpringMVC:学习笔记(4)——处理模型数据
  7. 2016.2.29(异常)
  8. Django-Celery异步发送激活邮件,以及注意点
  9. python嵌套循环注意事项_python循环嵌套的几种使用方法
  10. java,list集合类
  11. 笔记本linux版刚买回来怎么检查,新电脑买回来要怎么做
  12. mtk2503 GPS/操作系统/主板设计方式资料大全
  13. 行测测评——矩阵、圆形、环形三角图形数列推理解题技巧
  14. Gensim的维基百科语料库中文词向量训练错误整理
  15. 推荐一款备忘录便签APP简约款安卓版本
  16. 【每日蓝桥】10、一三年省赛Java组真题“剪格子”
  17. 中国武术高手要在郑州开比武大会?还请了马云做裁判?
  18. HRBUST 1162 魔女【DP】
  19. 苹果手机调试(ios)
  20. Vue之iconfont

热门文章

  1. Spring之面向切面编程AOP(三)
  2. 【题目解析】1015 Reversible Primes (20 分)_27行代码AC
  3. 满分简便代码:1009 说反话 (20分)
  4. 进行面向对象设计时,就一个类而言,应该仅有一个引起它变化 的原因,这属于()设计原则。【最全!最详细解析!】
  5. 给我往死里贪!——24行代码AC_今年暑假不AC HDU - 2037(贪心模板讲解)
  6. MYSQL查询语句待优化_mysql语句查询优化
  7. 计算机网络基础题解综合练习实验,计算机网络基础题解•综合练习•实验
  8. php封装webservice_PHP实现WebService的简单示例和实现步骤
  9. java与jquery的选择器区别_java day44【JQuery 基础:概念,快速入门,JQuery对象和JS对象区别与转换,选择器,DOM操作,案例】...
  10. if js 判断成绩等级_javascript://8种方法根据分数判断等级