持续应用程序内存增加(IOAccelResource)

5

我正在努力理解一个问题(在这个问题中提到)。背景是:基于cocos2d 2.0版本开发的回合制游戏,使用obj-c编写,不使用ARC,在准备应对一些iOS 7问题(我的问题,而非iOS7问题)的AppStore更新。

我的仪器和Instruments都没有显示任何泄漏、未释放的内存或其他异常。这在iOS 4、5、6.1下也是如此。然而,在提交之前的测试中,在设备上进行分析时,我发现游戏处于空闲状态时,每2分钟会增加1MB的内存占用(参见下面的图片)。

enter image description here

唯一能看到的就是IOAccelResource类别在生成捕获之间运行。

  1. 你有什么建议吗?

  2. 我找不到有关IOAccelResource的信息...你们中的任何人可以指点我正确的阅读方向吗?如果这确实与cocos2d有关,我不介意深入研究,但我不知道从哪里开始寻找。

  3. 此外,我想尽可能地运行“接近发布”的构建,并仍然能够测量随时间变化的内存占用。你能为我提供一种测量进程大小的方法吗?

    tia。


我遇到了一个相同的问题,与使用C++和Objective C ++编写的Cocos2d-x 2.2游戏有关。无法弄清楚它来自哪里 :( - Cory Trese
@CoryTrese 请看下面的回答:从外部运行发布和监控进程大小,进程大小稳定...相同的代码库,相同的一切,除了:没有调试,优化了大小和速度。 - YvesLeBorg
我也遇到了同样的问题,不同之处在于我正在使用OpenGL ES。因此,我猜想,即使您已经删除了UIAccelerometer和Cocos2D之间的关系,但是如果您观察到增长的分配图表,这让我认为即使是OpenGL也没有问题。现在,在您下面的评论中提到的一个事情是DisplayLink,它可以是Cocos2d和OpenGL ES共同用于将图形呈现到屏幕上的常见部分。如果是这种情况,那么iOS或Instrument就有问题。 - sam18
5个回答

2
据我所知,这是一个虚假的问题(可能是仪器故障)。当使用相同代码库的“发布”版本...即没有调试...并监视进程大小(即没有将调试进程附加到正在运行的进程上)时,内存泄漏就不存在了。

对我来说不是这样的。我遇到了这个问题,我在没有附加任何调试进程的情况下在发布上运行,而进程大小仍在增长。最奇怪的是,我的一些团队成员遇到了这个问题,而其他人则没有。我认为这可能与OpenGL有关,你们在使用吗? - Ricardo Sanchez-Saez
经进一步调查,编辑配置 > 运行 > 诊断 中的 启用僵尸对象 引起了这个问题。 - Ricardo Sanchez-Saez
这对我来说是新的。我每天都验证只有在调试时运行时才会出现内存泄漏。例如,使用xcode构建和运行,会出现内存泄漏。在xCode中停止进程,并在设备上重新启动应用程序(相同的构建),则不会出现内存泄漏。使用GL-2,这是使用cocos2d构建的游戏应用程序。但是我看到我的一个普通的vanilla UIsomething应用程序也有相同的证据。 - YvesLeBorg

1
我猜测:IOAccelResource 可能被 UIAccelerometer 使用。它听起来确实像是一个加速度计 I/O 类型的东西。
由于在 iOS 7 中,UIAccelerometer 已被弃用,但仍被 cocos2d 使用,也许苹果没有发现或关心这个问题。只是为了测试,请尝试从 cocos2d 中删除任何 UIAccelerometer 引用,看看是否会消失。发布版本不应影响 Instruments 内存监控,而档案构建从代码角度来说只是一个发布版本。

嗯嗯嗯……不错的 ewag!我会试一下然后很快回来。 - YvesLeBorg
也许这与以下问题有关:http://stackoverflow.com/questions/13231570/is-it-normal-that-my-cocos2d-app-increase-real-memory-usage-every-second。至少它似乎表明这可能是cocos2d的一个开关问题。我之前确实看到过这种行为,但并非在每个应用程序中都有。 - CodeSmile
好的...我修改了cocos2d以删除所有加速度计类的引用(仅在CCLayer中)...没有任何区别。现在正在调查可能的其他原因:Instruments。 - YvesLeBorg

1
你可以尝试使用Instruments中的heapshot分析来监控分配情况。这样可以让你知道额外内存是在哪里分配的。也许你已经尝试过了?

嗯......我在MIL-STD-Xcode5工具中搜索了“heap shot”,但没有找到它(其他线程提到过)。请问这是什么工具,如何“揭示”它? - YvesLeBorg
是的,他们在XCode5中稍微改变了术语。Heapshot分析现在被称为“Generations”,而获取heapshots现在被称为“Mark Generation”。你需要使用Allocations工具。在屏幕截图中看到“Statistics”时,单击它以浏览到Generations页面。 - Rob Segal
对于“Xcode”课程点赞。FYI:86.3%的爬行是IOAccelResource,在CS :: Display :: DisplayLink :: dispatch_item中深入研究。其余部分是我自己的东西,目前正在进行仔细调查。另外FYI,如果我使用AppCode(相同的方案,相同的构建配置)构建,并通过IDE运行仪器,我不会得到任何爬行。另一方面,如果我将仪器附加到正在运行的进程上,我会得到爬行。 - YvesLeBorg
听起来至少有一些线索。我以前没有使用过AppCode,所以无法评论它,但肯定有一些有趣的结果。另外,你可以尝试将Cocos2D中的任何加速度计代码切换到使用Core Motion。 - Rob Segal
哎呀呀...真是一团糟。看看Stefen的回答:我完全放弃了cocos2d中的加速计,泄漏还在那里。我怀疑IOAccelResource可能与GPU(硬件加速)更相关,而不是加速计。这就是为什么我在文献中找不到任何东西,即苹果的私有资料。这与泄漏(顺便说一句,Leak没有检测到)在DisplayLink中的事实相一致。 - YvesLeBorg

1
在“编辑方案>运行>诊断”中,“启用僵尸对象”选项可能会导致此行为。如果已启用,请务必禁用它。

1
Ricardo给出了一半的答案:Zombies对象是其中的一部分。您需要同时启用Zombies和附加进程才能获取creep。
总结如下:
  • 没有Zombies,没有内存creep。
  • 有Zombies,没有附加调试进程,没有内存creep。
  • 有Zombies,附加调试进程,内存creep。

我非常确定我已经在没有附加调试进程的Release编译版本中经历了内存泄漏(使用此方法进行内存报告)。另外,为什么你不编辑之前的问题而是添加一个新的问题呢? - Ricardo Sanchez-Saez
可能在我们的环境中有所不同:我主要使用cocos2d处理所有UI相关的事情。昨天我让一个应用程序运行了几个小时(没有僵尸进程,已附加调试器),没有出现任何异常。为了确保,我对cocos2d进行了修改,以便在整个过程中报告进程大小和fps,并与Instruments(监视器,不附加)进行比较。这件事真的很奇怪。 - YvesLeBorg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接