我正在使用 OpenGL ES 开发一个 2D iPhone 游戏,我一直在达到 24 MB 内存限制——我的应用程序不断崩溃并显示错误代码 101。我非常努力地寻找内存的去向,但 Instruments 中的数字仍然很多比我预期的要大。
我使用 Memory Monitor、Object Alloc、Leaks 和 OpenGL ES 工具运行应用程序。当应用程序被加载时,可用物理内存从 37 MB 下降到 23 MB,Object Alloc 稳定在 7 MB 左右,Leaks 显示两个或三个泄漏大小为几个字节,Gart 对象大小约为 5 MB,Memory Monitor 说应用程序占用大约 14 MB 的实际内存。我很困惑内存去了哪里——当我深入研究对象分配时,大部分内存都在纹理中,正如我所期望的那样。但是我自己的纹理分配计数器和 Gart 对象大小都同意纹理应该占用大约 5 MB。
我不知道分配任何其他值得一提的东西,并且 Object Alloc 同意。记忆去哪儿了?(如果这还不够,我很乐意提供更多细节。)
更新:我真的试图找到我可以分配这么多内存的地方,但没有结果。让我疯狂的是对象分配(~7 MB)和内存监视器(~14 MB)显示的实际内存使用量之间的差异。即使我忘记了巨大的泄漏或大块内存,它们仍然应该出现在 Object Allocations中,不是吗?
我已经尝试过通常的 嫌疑人,即。与UIImage
它的缓存,但这并没有帮助。有没有办法逐行跟踪内存使用“调试器风格”,观察每条语句对内存使用的影响?
到目前为止我发现了什么:
我真的在使用那么多内存。衡量真正的内存消耗并不容易,但是经过大量计算后,我认为内存消耗确实很高。我的错。
我发现没有简单的方法来测量使用的内存。内存监视器的数字是准确的(这些是真正重要的数字),但内存监视器无法告诉您内存的确切位置。Object Alloc 工具对于跟踪实际内存使用情况几乎毫无用处。当我创建纹理时,分配的内存计数器会上升一段时间(将纹理读入内存),然后下降(将纹理数据传递给 OpenGL,释放)。这没关系,但并不总是会发生——有时即使在纹理被传递到 OpenGL 并从“我的”内存中释放之后,内存使用率仍然很高。这意味着 Object Alloc 工具显示的分配内存总量小于实际总内存消耗,但大于实际消耗减去纹理 (
real – textures < object alloc < real
)。去搞清楚。我误读了编程指南。24 MB 的内存限制适用于纹理和表面,而不是整个应用程序。实际的红线稍远一些,但我找不到任何硬数字。共识是 25-30 MB 是上限。
当系统内存不足时,它开始发送内存警告。我几乎没有什么可释放的,但其他应用程序确实会将一些内存释放回系统,尤其是 Safari(它似乎正在缓存网站)。当内存监视器中显示的可用内存变为零时,系统开始查杀。
我不得不硬着头皮重写代码的某些部分以提高内存效率,但我可能仍在推动它。如果我要设计另一个游戏,我肯定会想到一些资源分页。对于当前的游戏,这非常困难,因为它一直在运动,并且加载纹理会妨碍,即使在另一个线程中完成。我会对其他人如何解决这个问题很感兴趣。
请注意,这些只是我的观点,不必太准确。如果我发现有关此主题的更多信息,我将更新该问题。我会保持这个问题的开放性,以防了解这个问题的人愿意回答,因为这些都是比其他任何东西更多的解决方法和猜测。