我正在使用OpenGL ES开发2D iPhone游戏,但不断遇到24MB内存限制的问题——我的应用程序经常崩溃,显示错误代码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对象大小都表示纹理应该占用大约5MB,我不知道其他地方还有哪些内存消耗。
我不知道是否还有其他值得一提的内存分配,Object Alloc也没有显示。内存到哪里去了?(如果这还不够,请告诉我更多细节)
更新:我尽力找到可能分配如此多内存的地方,但没有结果。让我疯狂的是Object Allocations(约7MB)和Memory Monitor显示的实际内存使用情况之间的差异(约14MB)。即使有很多泄漏或我忘记的巨大内存块,它们应该仍会在Object Allocations中显示出来,不是吗?
我已经尝试过通常的怀疑对象,比如UIImage及其缓存,但没有帮助。有没有一种类似“调试器”的方式来跟踪内存使用情况,逐行查看每个语句对内存使用情况的影响?
我目前所发现的情况:
我确实使用了那么多内存。很难测量真正的内存消耗,但经过大量计算,我认为内存消耗确实很高。这是我的问题。
我找不到测量内存使用的简单方法。内存监视器的数字是准确的(这些才是真正重要的数字),但内存监视器不能告诉您内存具体去了哪里。对象分配工具对跟踪真实内存使用几乎没有用处。当我创建纹理时,分配的内存计数器会暂时增加(将纹理读入内存),然后下降(传递纹理数据到OpenGL,释放)。这是可以接受的,但并不总是发生——有时即使纹理已经传递给OpenGL并从“我的”内存中释放,内存使用仍然很高。这意味着对象分配工具显示的分配总内存量比真实总内存消耗小,但比真实消耗减去纹理大(
真实 - 纹理 < 对象分配 < 真实
)。自己琢磨吧。我误读了编程指南。24 MB的内存限制适用于纹理和表面,而不是整个应用程序。实际的红线在更远的地方,但我找不到任何硬数据。共识是25-30 MB是上限。
当系统内存不足时,它开始发送内存警告。我几乎没有什么东西可以释放,但其他应用程序确实会将一些内存释放回系统,特别是Safari(它似乎正在缓存网站)。当内存监视器显示的可用内存为零时,系统开始终止进程。
我不得不咬紧牙关,重新编写了代码的一些部分,以更有效地使用内存,但我可能还是有压力。如果我要设计另一个游戏,我肯定会考虑一些资源分页。对于当前的游戏来说,这很困难,因为它一直在运动中,即使在另一个线程中加载纹理也会妨碍。 我非常想知道其他人如何解决这个问题。
请注意,这只是我的观点,并不一定很准确。如果我在这个话题上发现更多要说的,我会更新这个问题。我会保持这个问题开放,以便理解这个问题的人可以回答,因为所有这些方法都更像是权宜之计和猜测,而不是其他任何东西。