XCode/Instruments 未显示内存泄漏

发布于 2024-11-25 15:27:19 字数 392 浏览 0 评论 0原文

我正在关注斯坦福 iOS 开发讲座,并且我有一个计算器大脑类,它已在控制器中进行了分配初始化,但我还没有在控制器中释放它>dealloc。

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

    return brain;

}

我从 XCode 运行 ->使用 Performance Tool 运行,应用程序启动,没有出现泄漏,然后我单击 iOS 模拟器中的主页按钮,但什么也没有,然后我双击主页按钮并关闭应用程序,仍然没有任何结果。

我也做了构建和构建分析后它没有发现任何东西

你能告诉我为什么它没有捡到它吗?

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 released it in the dealloc.

- (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.

I also did Build & Analyse and it didnt spot anything

Could you let me know why its not picking it up?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

阳光下慵懒的猫 2024-12-02 15:27:19

看起来好像没有可检测泄漏。看这一行:

brain = [[CalculatorBrain alloc] init];

只要 brain 指向一个对象,该对象就不会被视为“内存泄漏”。如果在某个时候你这样做,

brain = nil;

那么泄漏就会被记录下来。释放容器对象也可以实现这一点,但是您确定它正在被释放吗? (例如,当程序退出时,它不会被释放。)

问题:泄漏检测器无法检测所有内存泄漏——这是数学上证明的事实。大多数检测器仅检测无法到达的对象,并且许多泄漏检测器特别容易受到漏报的影响——在 C 中,很难在运行时区分指针和整数之间的区别。

编辑:听起来您的应用程序只创建了一个控制器实例,而控制器也只创建了一个 CalculatorBrain 实例。如果您考虑一下内存泄漏到底是什么,您可以将其定义为程序不会将其释放回操作系统的未使用内存。

  • 当程序运行时,CalculatorBrain 始终在使用中,因此不是泄漏。
  • 当程序退出时,操作系统会自动回收进程使用的所有内存,因此程序退出后不会出现内存泄漏。

如果您想创建一个泄漏来看看它是什么样子,您可以在程序运行时多次创建一个新的 CalculatorBrain ,但忘记释放未使用的版本。在这种情况下,随着程序的运行,越来越多的 CalculatorBrain 实例将会累积。在 iOS 和其他嵌入式系统上,这通常会使您的程序崩溃。在现代 64 位计算机上,它将逐渐填满可用的交换空间,直到耗尽交换空间、地址空间或其他资源,从而导致程序崩溃或使系统非常无响应。

标准做法是不关心在整个程序运行中应该存在的对象的释放。

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". 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? (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. 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.

Edit: It sounds like your application only ever creates one instance of the controller, which only creates one instance of 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.

  • While the program is running, CalculatorBrain is always in use and therefore it is not a leak.
  • 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.

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. In this scenario, as your program runs, more and more instances of CalculatorBrain would accumulate. On iOS and other embedded systems, this will generally crash your program. 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.

Standard practice is to not care about deallocating objects which are supposed to exist for the entire program's run.

家住魔仙堡 2024-12-02 15:27:19

分析器无法找到所有内存泄漏。就其而言,将实例存储到 ivar 中不会从该方法中泄漏它,然后在 dealloc 中它不会意识到应该释放 ivar。 XCode 4可能在这方面有所改进,我不记得了(我自己仍然使用XCode 3)。

至于性能工具,请记住,只有在没有对象再保留对它的引用之前,该对象才会被视为泄漏。因此,即使您的控制器没有释放大脑,在控制器被释放(或接受大脑移植)之前,大脑也不会被视为泄漏。另请注意,在类似 *nix 的系统上,内存分配会在进程退出时自动清理。因此,如果您为进程生命周期中应该存在的对象分配内存(例如应用程序委托及其永久保留的任何内容)并依赖此行为在进程退出时释放它,那么这并不是真正的泄漏。

The analyzer cannot find all memory leaks. 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. XCode 4 may have improved in this respect, I don't recall (I still use XCode 3 myself).

As for the performance tool, remember that an object won't be considered leaked until nothing holds a reference to it anymore. 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). Also, note that on *nix-like systems, memory allocations are automatically cleaned up on process exit. So it isn't really a leak if you allocate memory for objects that should exist for the lifetime of your process (e.g. the app delegate and anything it permanently holds on to) and rely on this behavior to free it on process exit.

〗斷ホ乔殘χμё〖 2024-12-02 15:27:19

嗯...确实,泄漏无法检测到所有内存泄漏,但假设您正在这样做:

myIvarBrain=[self brain];

如果您将其交给 iVar(在您的类的 dealloc 中释放,并且没有访问器),实际上有完全没有泄漏。返回的 RC 是 1,并且自从您的班级取消分配后它将是 1。如果您不在 dealloc 中释放它,则应该等待类的 dealloc 来查看内存泄漏。
有道理吗?

Well... it's true that leaks can't detect all memory leaks, but let's say that you are doing this:

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. The returned RC is one and it will be one since the deallocation of your class. If you don't release it in the dealloc, you should wait a dealloc of your class to see a memory leak.
Does make sense?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文