无法找到内存泄漏的源

问题描述:

我正在编写一个应用程序(基本上是它的又一个iBooks克隆),它消耗了大量内存。根据输入数据的不同,内存占用空间可能会高达70-80 MB(如MemoryMonitor状态)或甚至更高。
它在一段时间内工作正常,但随着时间的推移它往往会增加其内存占用。
因此,让我们说你打开一本书,应用程序的内存占用从6MB增加到60MB。那么应该发生的是,关闭本书并将内存占用降低到6MB。而事实并非如此。它降低到〜30MB(根据MemoryMonitor),这导致了几次迭代中的崩溃。无法找到内存泄漏的源

现在有趣的部分。我试过铛静态分析器,但它没有显示任何问题(除了指出单身等)。
我试过使用泄漏工具,但他们表明我只有2-3KB的总数(应该是〜24MB +)。而且,我并不担心这些乐器实际上是在告诉我真相。我已经仔细检查了所有仪器报告的泄漏情况,我99%确定那里没有泄漏。
我试过使用分配工具,但它显示在关闭本书之后,内存占用降到6MB,这是所需的数字。但这并没有什么意义,因为如果是这样的话,应用程序就不会崩溃。 我也尝试使用资源字节图的openglES分析器,但它也显示没有泄漏或任何其他可疑。
我曾经信任的唯一工具是内存监视器,因为当它显示〜110MB真实内存时,我的应用程序总是会崩溃。但是,a)它没有显示分配内存的情况,b)当我尝试使用相同的应用程序构建多次运行它时,发现它的读数差异显着,从运行到运行(15-20MB差异,相同)。

所以所有的仪器都告诉我,我的代码是好的(除了内存监视器,这似乎是正确的,但没有用于任何测量),但它不断粉碎。
我不知道接下来应该做什么。我当然不能减少整体内存占用,我找不到内存泄漏(这仍然是我想要的方式)。

所以这是我的问题:
1)除了上面提到的那些之外,有没有找到泄漏的方法? iPhone的另一个profiler程序也许?
2)我已经读过关于某种碎片整理问题,例如当你分配/重新分配许多对象,然后应用程序不会将释放的块返回给操作系统,这可能会导致无法分配大块内存它太支离破碎,操作系统不会给你更多的内存。我从来没有见过一个好的话题。如果任何人都可以将链接留给相关主题,那将会很棒。
3)我试过禁用程序的几个部分,到目前为止看起来整个问题可能来自使用CoreText框架。我想听听任何曾经使用过这个框架的人,并且可以确认/否认那里存在任何问题。
4) - 其他建议 -

P.S.我没有包含任何代码片断,因为代码本身非常庞大,我无法将可疑代码的数量减少到合理的数量。

也许有点傻,但是当发生了大致类似的事情时,我意识到我已启用NSZombies 。从那以后,我的didFinishLaunching:在顶部有几条线:

if (getenv("NSZombieEnabled") || getenv("NSAutoreleaseFreedObjectCheckEnabled")) { 
    NSLog(@"NSZombieEnabled/NSAutoreleaseFreedObjectCheckEnabled enabled!"); 
} else { 
    NSLog(@"No NSZombieEnabled or NSAutoreleaseFreedObjectCheckEnabled"); 
} 
+0

诅咒的僵尸!就是这样! 我花了多少时间试图找出问题的根源。 我也很惊讶,内存分配/泄漏工具忽略了整个僵尸。 – Alexey 2010-07-30 07:19:30

+0

他们没有 - 他们把他们关闭,这就是为什么他们报告这么少。这在你的文本中对我来说是最大的暗示。 – Kalle 2010-07-30 08:03:26

+0

我不确定仪器是否将其关闭。在我手动禁用它们之后,内存监视器开始报告完全不同的数字,而来自泄漏/分配仪器的读数仍然相同(我正在运行带有分配+泄漏+操作系统+内存监视器的仪器)。 这就是为什么我认为他们忽略他们而不是关闭他们。 – Alexey 2010-07-30 09:06:07

问题是,泄漏只发现仍然保留的内存,您没有引用。

在你的情况下,你仍然有保留的内存,你也有参考。就泄漏而言,它不能说明你是否打算保留这种记忆,所以它什么也没说。

在你的情况下,最好的办法是使用对象Alloc工具 - 记录一个会话,然后对于一个成长记忆的区域alt-选择区域,并选择“保留和仍然存在”选项侧。现在通过所报告的对象并找出不应该保留的内容 - 一个好的起点是寻找仍然保留的任何自己的类并找出你认为被释放的内容。

较新的XCode也有一个工具,它结合了泄漏和对象分配,我不能再多说什么,因为它是在NDA下 - 但你可能想尝试一下。我不知道是否必须将它安装在单独的系统上才能访问改进的工具,虽然...