简体   繁体   English

XCode/仪器未显示 memory 泄漏

[英]XCode/Instruments not showing memory leaks

I'm following the Stanford iOS development lectures and I have a Calculator brain class which has been alloc init in a controller but I haven't release d it in the dealloc .我正在关注斯坦福 iOS 开发讲座,我有一个计算器大脑 class,它已经在dealloc中进行了分配alloc init ,但我还没有在交易中release它。

- (CalculatorBrain *)brain
{
    if (!brain) 
        brain = [[CalculatorBrain alloc] init];

    return brain;

}

I ran from XCode -> Run with Performance Tool and the app started and no leaks appeared, I then clicked the home button in the iOS Simulator and nothing, I then double clicked the home button and closed the app and still nothing.我从 XCode 运行 -> 使用性能工具运行,应用程序启动并且没有出现泄漏,然后我单击 iOS 模拟器中的主页按钮,什么也没有,然后我双击主页按钮并关闭应用程序,仍然没有。

I also did Build & Analyse and it didnt spot anything我也做了构建和分析,它没有发现任何东西

Could you let me know why its not picking it up?你能告诉我为什么它不捡起来吗?

It appears as if there is no detectable leak.似乎没有可检测到的泄漏。 Look at this line:看看这一行:

brain = [[CalculatorBrain alloc] init];

As long as brain points to an object, that object won't be considered a "memory leak".只要brain指向 object,object 就不会被视为“内存泄漏”。 If at some point you do this,如果你在某个时候这样做,

brain = nil;

Then the leak will register.然后泄漏将注册。 Deallocating the container object will also achieve this, but are you sure it's being deallocated?释放容器 object 也可以实现这一点,但您确定它正在被释放吗? (It won't be deallocated when your program exits, for example.) (例如,当您的程序退出时,它不会被释放。)

The problem: Leak detectors cannot detect all memory leaks -- this is a mathematically proven fact.问题:泄漏检测器无法检测到所有 memory 泄漏——这是经过数学证明的事实。 Most detectors only detect unreachable objects, and many leak detectors are especially susceptible to false negatives -- in C it is hard to tell the difference at runtime between a pointer and an integer.大多数检测器只检测无法到达的对象,而许多泄漏检测器特别容易出现误报——在 C 中,在运行时很难区分指针和 integer 之间的区别。

Edit: It sounds like your application only ever creates one instance of the controller, which only creates one instance of CalculatorBrain .编辑:听起来您的应用程序只创建了一个 controller 实例,它只创建了一个CalculatorBrain实例。 If you think about what a memory leak really is , you can define it as unused memory that your program does not release back to the operating system.如果您考虑真正的 memory 泄漏什么,您可以将其定义为您的程序不会释放回操作系统的未使用的 memory。

  • While the program is running, CalculatorBrain is always in use and therefore it is not a leak.当程序运行时, CalculatorBrain一直在使用,因此它不是泄漏。
  • When the program exits, the operating system automatically reclaims all memory used by your process, therefore there cannot be any memory leaks after a program exits.当程序退出时,操作系统会自动回收你的进程使用的所有 memory,因此程序退出后不会有任何 memory 泄漏。

If you want to create a leak to see what it looks like, you could create a new CalculatorBrain multiple times while your program is running, but forget to release the unused versions.如果你想创建一个泄漏来查看它的样子,你可以在程序运行时多次创建一个新的CalculatorBrain ,但忘记释放未使用的版本。 In this scenario, as your program runs, more and more instances of CalculatorBrain would accumulate.在这种情况下,随着您的程序运行,越来越多的CalculatorBrain实例会累积。 On iOS and other embedded systems, this will generally crash your program.在 iOS 和其他嵌入式系统上,这通常会使您的程序崩溃。 On a modern 64 bit computer it will gradually fill up the available swap space until you run out of swap, address space, or some other resource -- causing the program to crash or making the system very unresponsive.在现代 64 位计算机上,它会逐渐填满可用的交换空间,直到您用完交换空间、地址空间或其他一些资源——导致程序崩溃或使系统非常无响应。

Standard practice is to not care about deallocating objects which are supposed to exist for the entire program's run.标准做法是不关心释放整个程序运行时应该存在的对象。

The analyzer cannot find all memory leaks.分析仪无法找到所有 memory 泄漏。 As far as it is concerned, storing the instance into the ivar doesn't leak it from that method, and then in dealloc it doesn't realize that the ivar should be released.就它而言,将实例存储到 ivar 中不会从该方法中泄漏它,然后在 dealloc 中它没有意识到应该释放 ivar。 XCode 4 may have improved in this respect, I don't recall (I still use XCode 3 myself). XCode 4 可能在这方面有所改进,我不记得了(我自己仍然使用 XCode 3)。

As for the performance tool, remember that an object won't be considered leaked until nothing holds a reference to it anymore.至于性能工具,请记住 object 不会被视为已泄露,除非不再有对其的引用。 So even though your controller doesn't deallocate the brain, the brain won't be considered leaked until the controller is deallocated (or receives a brain transplant).因此,即使您的 controller 没有释放大脑,在 controller 被释放(或接受脑移植)之前,大脑也不会被视为泄漏。 Also, note that on *nix-like systems, memory allocations are automatically cleaned up on process exit.另外,请注意在 *nix-like 系统上,memory 分配会在进程退出时自动清理。 So it isn't really a leak if you allocate memory for objects that should exist for the lifetime of your process (eg the app delegate and anything it permanently holds on to) and rely on this behavior to free it on process exit.因此,如果您将 memory 分配给在进程生命周期内应该存在的对象(例如应用程序委托及其永久保留的任何内容)并依靠此行为在进程退出时释放它,这并不是真正的泄漏。

Well... it's true that leaks can't detect all memory leaks, but let's say that you are doing this:嗯...确实泄漏无法检测到所有 memory 泄漏,但是假设您正在这样做:

myIvarBrain=[self brain];

If you are giving it to an iVar (released in the dealloc of your class, and without accessors), actually there is no leak at all.如果您将它提供给 iVar(在 class 的 dealloc 中发布,并且没有访问器),实际上根本没有泄漏。 The returned RC is one and it will be one since the deallocation of your class.返回的 RC 为 1,自从您的 class 释放后,它将为 1。 If you don't release it in the dealloc, you should wait a dealloc of your class to see a memory leak.如果您不在 dealloc 中释放它,您应该等待 class 的 dealloc 以查看 memory 泄漏。 Does make sense?有意义吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM