2013-01-21 39 views
3

我们正在为iPhone制作游戏。我们已经完成了开发并试图优化现在的游戏内存。我们注意到,当我们在游戏中加载特定的MVC时,并非所有分配的内存都被释放(大约增加了4-5MB)。如果您持续播放该游戏15-20分钟,这会使游戏的内存使用量非常高,并且在发出低内存警告后游戏最终崩溃。减少iPhone应用程序的内存使用量

这是我绑
1.运行静态分析仪上的游戏和固定所有的内存泄漏和警告。
2.手动检查所有类的dealloc是否被调用。这似乎很好。
3.也尝试在Xcode中运行Allocations工具,但其中的大部分条目都是CFStrings,mallocs和CFNumbers等,但并不真正告诉我的哪些类来自它们。有更好的方法来使用分配工具吗?

我也有一对夫妇的内存相关的问题
1.我们使用在游戏中很多地方自动释放对象,而无需使用一个自动释放池。我的理解是自动释放的对象应该在下一次运行循环中释放,并且不应该造成如此大的问题?
2.另外,如果我通过xib文件加载图像,它们会被iOS缓存。他们是否也会占用内存?

我该如何解决我的内存使用问题。任何帮助,将不胜感激。 谢谢!

+1

我敢肯定,autoreleased对象需要一个池来释放该线程...... – DavidAndroidDev

+0

@DavidAndroidDev真的,但应用程序的主要autorelease池通常就足够了。如果需要,您可以拥有自己的autorelease池,但通常不需要。 – Rob

+0

@Rob不是只对主线程是真的吗?如果你在后台线程中创建对象,我相信它需要自己的池。我不确定OP的应用程序是否正在运行任何辅助线程,但我记得需要一个辅助线程的自动释放池。我会看看我能否找到我发现的地方。 – DavidAndroidDev

回答

2

如果您正在“制作过程中”,则应该使用ARC (automatic reference counting)。一旦你全部转换为ARC,你将不再需要这些autorelease对象,编译器会在适当的时候释放对象。如果您发现某些对象池仍然失去控制,您可以使用@autoreleasepool声明来创建自己的自动释放池。

我认为切换到ARC将帮助你,并使你的进一步发展更简单。转换为ARC后,再次在仪器中对您的应用程序进行配置文件并缩小任何创建大型对象池的代码。

如果您选择不转换为ARC,根据您的解释,听起来您可以对您所指的视图有一个保留周期。确保视图实际上是通过追踪它保留的每个位置而被释放的。

+0

因为我们几乎完成了开发工作,所以现在切换到ARC将会非常困难和耗时。我已经检查过所有视图控制器和涉及的其他类的调用的零售周期和dealloc。 – tbag

4

一对夫妇的想法:

  1. 是否使用Core Foundation的课?确保针对您调用CFRelease(或转移所有权,然后releaserelease或 Objective-C对象)名称中的CreateCopy的核心基金会呼叫的每个对象。

  2. 您是否也在乐器中使用过Leaks工具?我假设如此,但你没有提到它。请参见仪器用户指南中的Finding Leaks in your App

  3. 您是否正在通过imageNamed加载图片?缓存图像,并不好释放它们。使用imageWithContentsOfFile并手动管理您的缓存更安全。

  4. 我假设你的视图控制器的dealloc被调用,并且你释放所有与类属性/ ivars相关的对象?

  5. 你有僵尸打开吗?这对于诊断目的非常有用,但是直到关闭僵尸时才会释放内存。

2

什么罗布和克里斯说,那么这样做:

使用分配仪器配置为只跟踪活动的拨款,并记录引用计数。

当Allocations收集数据,然后暂停您的应用程序时,使用您的应用程序。

暂停时,按实时字节和#生活排序是您最有用的视图。对于利用Foundation集合类的以数据为中心的应用程序,* String,* Dictionary和* Array的组合可能是最常见的。

这没关系。如果您点击其中任何一个的详细信息,您将获得当前在内存中的所有实例的长列表。你可以po <addr>其中任何一个来看看他们是什么。您还可以滚动浏览列表,查看哪些功能是最常见的分配负责。同样,您可以点击任何实例来查看它的分配位置和/或为什么它可能仍然存在。

同样,您可以从概览表开始,按#Living排序,然后向下滚动到其中一个类的第一个实例。如果这个班级扎根 - 掌握了大量数据,那么消除或优化这是一个很好的开始。

而且,当然,不要忘记heapshot analysis是一个非常有效的记忆增长分析分析工具。