内存泄露检测

转载 2015年07月07日 15:06:43

1、运行Demo。

先下载一个实现准备好的内存泄露的Demo吧:leak app

下载下来,打开运行,程序是一个寿司的列表,列出各种寿司卷。试着选择里面的几行,应该是选第二行的时候就崩溃了。崩溃截图:



在崩溃的地方断住了,知道crash的地方了,但是不知道具体crash的原因。


2、设置NSZombieEnabled

这是一个 “EXC_BAD_ACCESS”错误。我们打开XCode的选项:“NSZombieEnabled” 。在crash时可能会给你更多的一些提示信息。

设置步骤:1


2:勾上红色框里的


运行,按刚才的操作选中其中的cell。再次crash,这次在output窗口会看到多了一项错误信息:

2012-11-28 13:22:08.911 PropMemFun[2132:11303] *** -[CFString respondsToSelector:]: message sent to deallocated instance 0x713ebc0

大概意思是:向已释放的内存发送消息。也就是说使用了已释放的内存,在C语言相当于使用了“野指针”


看了下crash的这个语句,sushiString应该是没问题的,它是从stringWithFormat初始化出来的。那就是_lastSushiSelected的问题。

_lastSushiSelected指向了sushiString,sushiString是一个autorelease变量。 在第二次点击时,使用的是sushiString已经被释放,所以crash了。那为_lastSushiSelected保留一下,就可以用了。代码修改如下:

  1. <span style="font-size:14px;">    _lastSushiSelected = [sushiString retain];  
  2. </span>  

运行,这时候不崩溃。


3、分析内存泄露(shift+command+b)

app不crash了,那看看有没有内存泄露。用XCode的Analyze就能分析到哪里有内存泄露


分析之后可以看到:


这里提示alertView没被释放,有内存泄露,那我们释放

    [alertView release];

再分析,这个问题解决了。


4、使用Instruments的leaks工具

分析内存泄露不能把所有的内存泄露查出来,有的内存泄露是在运行时,用户操作时才产生的。那就需要用到Instruments了。
 
按上面操作,build成功后跳出Instruments工具,选择Leaks选项,这时候寿司程序也运行起来了,选中list中的项,拖动等操作后,工具显示效果如下:


大家可能都能猜到,红色的柱子表示内存泄露了。怎么通过这个工具看到在哪泄露了呢?
先在工具栏按下红色的圆形按钮,把工具监视内存的活动停下来。选择Leak,然后点中间十字交叉那,选择Call Tree.


这时候左下角的Call Tree的可选项可以选了。选中Invert Call Tree 和Hide System Libraries,显示如下:

这时候内存泄露的具体代码找到了,在右边的红色框框里指定了哪个方法出现了内存泄露。
你只要在这些方法上双击,就会跳转到具体的代码,哈哈,是不是很方便。

这里应该是提示100%内存会泄露。

6、解决内存泄露问题

问题找到了,那就解决吧

关于:tableView:didSelectRowAtIndexPath ,分析下它的内存过程:

  1. sushiString变量通过autorelease创建,它的引用计数是1.   
  2. 这行代码使得引用计数增加到2, _lastSushiSelected = [sushiString retain];
  3. 这个方法结束时,sushiString的autorelease生效了,这个变量的引用计数减少为1
  4. 当再次执行tableView:didSelectRowAtIndexPath这个方法时,_lastSushiSelected被赋值了新指针,老的_lastSushiSelected的引用计数还是1,没有被释放,产生了内存泄露。

怎么解决呢?

_lastSushiSelected = [sushiString retain];之前把原来的release就ok了:

  1. [_lastSushiSelected release];  
  2.     _lastSushiSelected = [sushiString retain];  


关于:tableView:cellForRowAtIndexPath

这个比较明显,sushiString被alloc和init之后就没有释放,可以用stringWithFormat来调用autorelease,代码如下:

  1. NSString *sushiString = [NSString stringWithFormat:@"%d: %@", indexPath.row, sushiName];  

好了,泄露都fix了,再用工具分析看看,这时候你再点,再拖,再怎么操作,都没有内存泄露了。表明内存泄露被堵住了。

这是本文修复好的app代码:no LeakApp

C++内存泄露和检测

C++中的内存泄露的原因和内存泄露的检测方法。
  • KangRoger
  • KangRoger
  • 2014年09月16日 16:37
  • 15395

java内存泄漏的定位与分析

1、为什么会发生内存泄漏 Java如何检测内在泄漏呢?我们需要一些工具进行检测,并发现内存泄漏问题,不然很容易发生down机问题。 编写java程序最为方便的地方就是我们不需要管理内存的分...
  • lc0817
  • lc0817
  • 2017年03月27日 22:14
  • 1235

VS2010检查内存泄露

VS2010中的C++程序内存泄露检测     对于MFC程序是支持内存检测的。对于非MFC程序而言,CRT有一套内存泄露的函数,最常用的是 _CrtDumpMemoryLeaks();如下所示: #...
  • yiranant
  • yiranant
  • 2015年08月21日 13:05
  • 1248

Xcode 静态分析与内存泄漏检查

Xcode 静态分析与内存泄漏检查
  • zhuquan0814
  • zhuquan0814
  • 2016年04月16日 15:30
  • 3637

VC++内存泄漏的检测与定位

VC++内存泄漏的检测与定位 内存泄漏信息查看(MFC、非MFC) 位置定位(MFC、非MFC) 非MFC查看内存泄露信息:关键代码#include "crtdbg.h" //添加该头文件 _Crt...
  • xuleisdjn
  • xuleisdjn
  • 2016年11月09日 15:38
  • 1368

Linux 内存泄露检测技巧

由于 C 和 C++ 程序中完全由程序员自主申请和释放内存,稍不注意,就会在系统中导入内存错误。同时,内存错误往往非常严重,一般会带来诸如系统崩溃,内存耗尽这样严重的后果。无论何时何地发生内存泄漏,都...
  • u010193457
  • u010193457
  • 2015年10月16日 11:44
  • 2769

VS检测内存泄漏,定位泄漏代码位置方法

1、什么是内存泄漏? 内存泄漏指的是在程序里动态申请的内存在使用完后,没有进行释放,导致这部分内存没有被系统回收,久而久之,可能导致程序内存不断增大,系统内存不足……引发一系列灾难性后果;(关于程序申...
  • mfcing
  • mfcing
  • 2015年01月13日 11:13
  • 10083

Visual C++内存泄露检测工具(VLD)

简述C/C++ 程序越复杂,内存的管理显得越重要,稍有不慎就会出现泄漏。如果内存泄漏不是很严重,在短时间内对程序不会有太大影响,这也使得内存泄漏问题有很强的隐蔽性,不易被发现。然而不管内存泄漏多么轻微...
  • u011012932
  • u011012932
  • 2016年10月11日 17:42
  • 2843

ios学习路线—Objective-C(检查内存泄露方式(Instruments))

Time Profiler(时间探测器) 现在开始运行app,搜索一些图片,这时候你发现查找一个结果太慢了,而且搜索结果列表页面滚动起来也是让人无法忍受的, 首先,确保工具栏中的视图选择有选择的所...
  • dubo413392749
  • dubo413392749
  • 2016年06月15日 15:50
  • 1112

Android内存泄露检测工具和实际开发中遇到的内存泄露问题解析

介绍内存泄露是平常开发中经常遇到的,有些时候稍不注意就会发生,而且还不易察觉,这就需要工具来帮助检测。本文主要介绍内存检测工具和我在开发中遇到的内存泄露问题和解决方案。内存泄露的原理具体的原理涉及到虚...
  • Card361401376
  • Card361401376
  • 2016年05月23日 17:41
  • 2224
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:内存泄露检测
举报原因:
原因补充:

(最多只允许输入30个字)