内存泄漏

内存泄漏(memory leak)是指由于疏忽或错误造成了程序未能释放掉不再使用的内存的情况。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,失去了对该段内存的控制,因而造成了内存的浪费

一、内存泄漏情况:

1.程序循环new创建出来的对象没有及时的delete掉,导致了内存的泄露; 

2.delete掉一个void*类型的指针,导致没有调用到对象的析构函数,析构的所有清理工作都没有去执行从而导致内存的泄露

3.new创建了一组对象数组,内存回收的时候却只调用了delete而非delete []来处理,导致只有对象数组的第一个对象的析构函数得到执行并回收了内存占用,数组的其他对象所占内存得不到回收,导致内存泄露; 

4.没有将基类的析构函数定义为虚函数。在类的继承中,如果有基类指针指向派生类对象,那么用基类指针delete时,如果基类的析构函数不是virtual,派生类对象中自己的那部分内存将无法被释放。

二、

对于C和C++这种没有垃圾回收机制的语言来讲,我们主要关注两种类型的内存泄漏:

(1)堆内存泄漏 (Heap leak)。对内存指的是程序运行中根据需要分配通过malloc,realloc new等从堆中分配的一块内存,再是完成后必须通过调用对应的 free或者delete 删掉。如果程序的设计的错误导致这部分内存没有被释放,那么此后这块内存将不会被使用,就会产生Heap Leak. 

(2)系统资源泄露(Resource Leak).主要指程序使用系统分配的资源比如 Bitmap,handle ,SOCKET等没有使用相应的函数释放掉,导致系统资源的浪费,严重可导致系统效能降低,系统运行不稳定。 

三、内存泄漏检测与避免

(1). valgrind工具

将程序编译生成可执行文件后执行 valgrind --leak-check=full ./程序名 

会输出以下信息

      1、对未初始化内存的使用;

       2、读/写释放后的内存块;

       3、读/写超出malloc分配的内存块;

       4、读/写不适当的栈中内存块;

       5、内存泄漏,指向一块内存的指针永远丢失;

       6、不正确的malloc/free或new/delete匹配;

 

(2) glibc提供了一个检查内存泄漏的方法, 前提是你的程序使用glibc的标准函数 分配内存(如malloc, alloc...): 
1. 在需要内存泄漏检查的代码的开始调用void mtrace(void) (在mcheck.h中有声明). mtrace为malloc等函数安装hook, 用于记录内存分配信息. 在需要内存泄漏检查的代码的结束调用void muntrace(void). 
注意: 一般情况下不要调用muntrace, 而让程序自然结束. 因为可能有些释放内存代码要到muntrace之后才运行. 
2. 用debug模式编译被检查代码(-g或-ggdb) 
3.定义一个环境变量,用来指示一个文件,该文件用来输出log信息,如export MALLOC_TRACE=mymemory.log; 
4. 运行被检查程序, 直至结束或muntrace被调用. 
5. 用mtrace命令解析内存分配Log文件,,如mtrace testmem $MALLOC_TRACE ,  ,如果有内存泄漏, mtrace会输出分配泄漏内存的代码位置,以及分配数量.等其他东西

除了mtrace,1.还有一些检查内存泄漏的工具比如ccmalloc,valgrind,beam

静态分析工具:beam,支持windows、linux,不仅可以检查内存泄漏,还可以坚持未出化的变量,废弃的空指针, 冗余计算

  像C/C++编译器,输入命令编译。

(3)通过智能指针来避免内存泄漏

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值