博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux下内存泄漏工具
阅读量:5030 次
发布时间:2019-06-12

本文共 3394 字,大约阅读时间需要 11 分钟。

概述

  内存泄漏(memory leak)指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况,在大型的、复杂的应用程序中,内存泄漏是常见的问题。当以前分配的一片内存不再需要使用或无法访问时,但是却并没有释放它,这时就出现了内存泄漏。尽管优秀的编程实践可以确保最少的泄漏,但是根据经验,当使用大量的函数对相同的内存块进行处理时,很可能会出现内存泄漏。

  内存泄露可以分为以下几类:

  1. 常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。
  2. 偶发性内存泄漏。发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。所以环境和测试方法对检测内存泄漏至关重要。
  3. 一次性内存泄漏。发生内存泄漏的代码只会被执行一次,或者由于上的缺陷,导致总会有一块且仅一块内存发生泄漏。比如,在一个Singleton类的构造函数中分配内存,在析构函数中却没有释放该内存。而Singleton类只存在一个实例,所以内存泄漏只会发生一次。
  4. 隐式内存泄漏。程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏。

内存泄漏检测工具

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

  1、mtrace

  应用环境: 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)等等

  如何获取:

 

  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

  如何获取:

  4、debug_new

  应用环境:Linux/Windows

  编程语言:C++

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

  结果输出:控制台console

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

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

  如何获取:

 

总结

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

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。

  

转载于:https://www.cnblogs.com/guochaoxxl/p/6970090.html

你可能感兴趣的文章
安卓动画有哪几种?他们的区别?
查看>>
Nodejs学习总结 -Express入门(一)
查看>>
web前端优化
查看>>
ssh 连接原理及ssh-keygen
查看>>
vs2013编译qt程序后中文出现乱码
查看>>
【转】IOS数据库操作SQLite3使用详解
查看>>
Android官方技术文档翻译——ApplicationId 与 PackageName
查看>>
【转】ButterKnife基本使用--不错
查看>>
【转】VS2012编译出来的程序,在XP上运行,出现“.exe 不是有效的 win32 应用程序” “not a valid win32 application”...
查看>>
函数中关于const关键字使用的注意事项
查看>>
微信架构(转)
查看>>
Web项目中的路径问题
查看>>
js随机数的取整
查看>>
关于解析漏洞
查看>>
十大经典预测算法(六)---集成学习(模型融合算法)
查看>>
用php做一个简单的注册用户功能
查看>>
一款基于css3的3D图片翻页切换特效
查看>>
Feign使用Hystrix无效原因及解决方法
查看>>
Sizeof与Strlen的区别与联系
查看>>
hadoop2.2.0_hbase0.96_zookeeper3.4.5全分布式安装文档下载
查看>>