`
shappy1978
  • 浏览: 704611 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

【转】找到 iPhone 内存泄露:Leaks 工具指引

阅读更多

找到 iPhone 内存泄露:Leaks 工具指引

时间: 2010-08-19 13:42 点击:399 次

最近常使用Instruments这个工具,我发现它对追踪游戏中的内存泄露非常有帮助。自从发现Instruments如此有用后,我就觉得写一篇文章介绍如何使用它来追踪内存泄露对其他人也会有帮助。

  最近常使用Instruments这个工具,我发现它对追踪游戏中的内存泄露非常有帮助。自从发现Instruments如此有用后,我就觉得写一篇文章介绍如何使用它来追踪内存泄露对其他人也会有帮助。

什么是内存泄露?我为什么要关心内存泄露?

…此段省略…
访问维基百科可以获得更多关于内存泄露的信息。

我如何知道内存泄露了?

一些内存泄露可以很容易地通过阅读代码来发现,另一些就要困难点了,这就是为什么需要Instruments 的原因。Instruments 有一个“Leaks”工具,它会准确地告诉你什么地方发生了内存泄露,以便你能定位和修复泄露问题。

例子程序

我写了一个例子程序,它有两个地方会发生内存泄露,一个在 Objective-C 视图控制器中,另一个在 C++ 类中。例程可以从这里获得。下边的代码是从例程里摘录的,包含了我们需要追踪内存泄露的代码。

// Leaky excerpts – see GitHub for complete source

- (void)viewDidLoad {
[super viewDidLoad];

LeakyClass* myLeakyInstance = new LeakyClass();
delete myLeakyInstance;

mMyLeakyString = [[NSString alloc] initWithUTF8String:”I’m a leaky string.”];

[self doSomethingNow];
}

- (void) doSomethingNow
{
mMyLeakyString = [[NSString alloc] initWithUTF8String:
“Look, another alloc, but no release for first one!”];
}

// Leaky excerpts – see GitHub for complete source

LeakyClass::LeakyClass()
{
mLeakedObject = new LeakedObject();
}

LeakyClass::~LeakyClass()
{
}

我会先在 Debug 模式编译InstrumentsTest,并在 iPhone 上运行。完成这步,我会启动 Instruments。



当你启动 Instruments,你可以从一堆 Instruments 工具里选择你需要的。在左手边选择 iPhone,在右手边的图标里双击“Leaks”工具:



之后你会看到下边的窗口:



请确保 iPhone 已经连接到了你的电脑,在这个窗口的左上角,你会看到一个下拉菜 单,写着“Launch Executable”。单击它,并确保选中的是你 iPhone(而不是你的电脑)作为活动设备。然后移动到“Launch Executable”,你可以看到一个包含了所有已安装 iPhone 程序的列表。找到你希望运用“Leaks”工具的程序(本例中是 InstrumentsTest)并单击它。



你已经准备好了。单击红色的“Record”按钮,它会启动程序并开始记录程序里的每个内存分配操作。它会每10秒自动地检测内存泄露。



你 可以改变多少时间自动检测一次,你也可以手动进行检测(检测内存泄露的时候程序会停顿大约3-5秒钟,如果你想边进行测试边进行内存检测的话,这种停顿将 会干扰到你)。我一般是设置成手动控制,在我需要的时候才单击“Check for leaks”按钮(例如:在loading新的游戏模式之后检测一下,在退出游戏返回 MM 的时候检测一下)。单击“Leaks”,并使用右上角的 View->Detail 按钮来设置和查看选项值,在这个例子里,我将其设置成 auto。



程序在运行一段时间之后,自动内存检测将会发现两处内存泄露。太棒了!现在该干什么呢?



Extended Detail 视图

Instruments 非常懒,它不会明显地指出下一步该干什么。你需要注意的是窗口底部的那一排按钮。看见两个矩形组成的那个按钮了吗?讲你的鼠标停留在上边,它会提示“Extended Detail View”。



单击这个按钮,右边将会弹出一个窗口,里边提供了各种关于内存泄露的详细信息。单击一个内存泄露,Extended Detail 视图将会显示泄露的内存代码的完整调用堆栈。在我们上边的例子中,单击第一个内存泄露提示,它发生在 [NSString initWithUTF8String]。如果你选中调用堆栈里的高亮步骤,你会看到程序最后一次调用是 [InstrumentsTestViewController viewDidLoad]。

双击 Extend Detail 视图中的某行,它会打开 XCode 窗口并显示出问题的代码,这是非常棒的功能。



在本例中,第一次 NSString 分配的时候出现了泄露,你需要做一些处理。这是个非常简单的例子,但找到为什么会发生泄露则要麻烦些。让我们仔细看一下例子。在 viewDidLoad 当中,我们为字符串分配到了内存,如下所示:

mMyLeakyString = [[NSString alloc] initWithUTF8String:”I’m a leaky string.”];

在 dealloc 当中我们用如下方式来释放

[mMyLeakyString release];

你的直觉可能是这样不会发生泄露,但搜索代码中所有用到了 mMyLeakyString 的地方,在 doSomethingNow 中,它是这样用的:

mMyLeakyString = [[NSString alloc] initWithUTF8String:
“Look, another alloc, but no release for first one!”];

注意,我们声明了一个新的字符串,并且将 mMyLeakyString 指向了它。这里的问题是我们没有在更改 mMyLeakyString 的指向前释放它原 来指向的内存。所以原始的字符串依然在堆中,并且我们没有办法释放这部分内存。dealloc 里的 release 操作实际释放的是我们在 doSomethingNow 中声明的字符串所占内存,因为这才是指针所指。
为了修复这个问题,我们可以把 doSomethingNow 改成下边的代码:

- (void) doSomethingNow
{
[mMyLeakyString release];
mMyLeakyString = [[NSString alloc] initWithUTF8String:
“Look, another alloc, but released first one!”];
}

这段代码做的是在我们指定 mMyLeakyString 到新的字符串前释放第一个字符串所占内存。重新编译运行程序,你会看到只有一个内存泄露。当然,在项目中可能有更好的方式来处理 NSString,但如果你这样处理的话可以修复这个泄露问题。
让我们看看第二个泄露问题。单击泄露提示看什么导致了内存泄露。发现这个泄露来自于 LeakyClass::LeakyClass() 构造函数:




在调用堆栈中双击它,出问题的代码将会再次出现在 XCode 中。



我们看到在构造函数里声明了一个新的 LeakedObject 对象,但是析构函数没有删除,这样不好。对于每一个 new 操作,都需要有与之对应的 delete 操作。所以我们把析构函数改变成下边的样子:

LeakyClass::~LeakyClass()
{
if (mLeakedObject != NULL)
{
delete mLeakedObject;
mLeakedObject = NULL;
}
}

重新编译运行,没有内存泄露了!
我选择这两个例子,虽然非常简单,但他们展示了 Instruments 可以用来追踪 Object-C 和 C++ 中的内存泄露。
修复你的内存泄露问题吧,记住,没有内存泄露的程序才是一个好程序。

原文地址:http://www.mobileorchard.com/find-iphone-memory-leaks-a-leaks-tool-tutorial/,感谢 CocoaChina 会员“ipqn”的翻译。

分享到:
评论

相关推荐

    Leaks内存泄露检测

    Leaks工具是苹果提供的一款强大的内存分析工具,用于检测应用程序中的内存泄露情况。本篇文章将详细阐述Leaks检测内存泄露的基本原理、使用方法,以及如何在实际开发中避免内存泄露。 首先,内存泄露是指程序在申请...

    windows下c++内存泄露检测工具使用方

    ### Windows 下 C++ 内存泄露检测工具使用详解 在 Windows 平台下进行 C++ 开发时,内存管理是一项非常重要的任务。由于 C++ 语言本身的特性,开发者需要手动管理内存分配与释放,这就很容易导致内存泄露的问题。...

    内存泄露检测工具

    Windows Leaks Detector 工具可以检测 Windows 应用程序中的内存泄漏问题,并提供了详细的错误信息,以便开发者快速解决问题。 12. SAP Memory Analyzer:是一个开源的 JAVA 内存分析软件,用于检测 JAVA 程序中的...

    内存泄漏检测工具

    针对这个问题,专门的“内存泄漏检测工具”应运而生,如“js内存泄漏检测工具”和“IE Javascript leaks detector”。 1. **JavaScript内存管理** JavaScript的内存管理主要依赖于垃圾回收机制(Garbage ...

    GDB查找内存泄露

    此外,除了GDB,还可以使用Valgrind、LeakSanitizer等工具进行更深入的内存泄漏检测。Valgrind提供了一整套内存错误检测工具,包括Memcheck,它能检测内存泄露、使用未初始化的内存和内存越界等问题。LeakSanitizer...

    C++中内存泄露检测工具

    2. Leaks:Leak是Apple开发的一款内存检测工具,主要用于Mac OS X和iOS平台。它能够检测出Cocoa框架中的内存泄露,并提供详细的堆栈跟踪信息。 3. AddressSanitizer(ASan):ASan是Google开发的一个内存错误检测...

    Iframe内存泄露分析

    检测内存泄漏的工具和手段确实有限,仅有的两个工具(JavaScript Memory LeakDetector 和 sIEve )都不太好用,不像 Java 里面的一些工具能精准定位。因此,需要通过经验预测最有可能泄漏的几个点,再通过排除法,...

    如何在xcode里面使用内存泄露查找工具

    本文将详细讲解如何在Xcode中使用内存泄露查找工具,比如Memory Leaks和Instruments。 首先,了解什么是内存泄露是必要的。内存泄露指的是程序在申请内存后,未能在不再使用时及时释放内存,导致可用内存逐渐减少,...

    Detected memory leaks简单检测方法

    3. 此时可以查看当前的堆栈跟踪信息,找到导致内存泄漏的具体代码行。 **步骤三:分析与修复** 1. 分析代码:仔细检查导致内存泄漏的代码段,通常情况下是忘记释放分配的内存或者对象的作用域设计不合理。 2. 修改...

    Java内存泄漏排除工具mat

    为了有效地排查和解决这类问题,开发者通常会借助专业工具,而“Java内存泄漏排除工具MAT”(Memory Analyzer Tool)就是一个强大的诊断工具。MAT是由Eclipse基金会开发的,用于分析Hprof格式的堆转储文件,帮助...

    CString内存泄露HTML.rar

    - **内存泄露识别**:如何通过工具和技巧定位和识别由CString引发的内存泄露问题。 - **解决策略**:提供了多种解决CString内存泄露的方法,可能包括正确使用`Release()`函数,避免不必要的复制等。 - **线程安全**...

    检测内存泄漏检测内存泄漏

    ### 检测内存泄漏:理解与实践 #### 一、引言 内存泄漏是程序设计中的一个常见问题,尤其在使用C/C++等需要手动管理内存的语言时更为普遍。内存泄漏不仅会消耗系统的资源,还可能导致应用程序运行缓慢甚至崩溃。...

    Finding memory leaks发现内存的泄漏(6KB)

    这篇“Finding memory leaks发现内存的泄漏”可能是关于如何定位和解决内存泄漏的技术指南。 在C++编程中,程序员需要手动管理内存,通过`new`关键字申请内存,然后通过`delete`关键字释放内存。如果忘记释放或错误...

    iPhone Instruments工具使用

    本文将详细介绍如何使用Instruments工具来检测和解决内存泄露问题。 内存泄露是指程序在分配内存后,未能正确释放不再使用的内存,导致系统资源浪费。长期累积的内存泄露可能导致应用程序崩溃或性能下降。因此,...

    VLD内存泄漏检测工具使用

    VLD内存泄漏检测工具使用 VLD(Very Lazy Debugger)是一款功能强大且广泛使用的内存泄漏检测工具,主要用于检测C++程序中的内存泄漏问题。下面我们将详细介绍VLD内存泄漏检测工具的使用方法。 一、下载和安装 VLD...

    如何使用Leak检查内存泄漏

    在iOS应用开发中,内存管理是一项至关重要的任务,特别是对于iPhone开发者来说,因为与使用具有自动垃圾回收机制的语言(如.NET或Java)不同,Objective-C(通常用于iPhone开发)要求程序员手动管理内存。内存泄漏是...

    vld(Visual Leak Detector 内存泄露检测工具 源码)

    相比较其它的内存泄露检测工具,它在检测到内存泄漏的同时,还具有如下特点:  1、 可以得到内存泄漏点的调用堆栈,如果可以的话,还可以得到其所在文件及行号;  2、 可以得到泄露内存的完整数据;  3、 可以...

    vs内存泄漏检测工具

    1、解压Visual Leak Detector.zip,解压...No memory leaks detected. Visual Leak Detector is now exiting. ps:上面用E:\install\Visual Leak Detector\lib\Win32的dll文件,跟本机系统无关,因为项目是win32项目

    IE内存泄漏检测工具 Drip-0.5

    Drip(Detection of Recursive Leaks in IE,IE递归泄漏检测)是由Microsoft员工Steve Sounders开发的一个轻量级工具,用于检测IE中的JS内存泄漏。Drip-0.5是该工具的一个特定版本,它提供了更为稳定和精确的检测...

Global site tag (gtag.js) - Google Analytics