2011-08-22 26 views
0

对不起,模糊的标题,但不太清楚如何总结这一个。iPad1内存谜与我的纹理密集型游戏应用程序

事实是:

  • 我有一个已经批准了苹果公司,并在App Store游戏。
  • 这是一个通用的应用程序。它在小屏幕上使用专为320x480设计的纹​​理,并在视网膜和iPad屏幕上使用更大的纹理(大约四倍大)。
  • 在开发它时,我有时会在控制台日志中看到低内存警告,但在阅读完这些内容后,似乎他们往往有些虚假/不重要,并且无论如何我没有崩溃,测试人员各种设备(iPod Touch第二代,iPod Touch第四代,iPhone3,iPhone4,iPad1,iPad2)没有看到崩溃。
  • 当我开始通过TestFlightApp将应用程序发布到更广泛的beta测试者时,我收到了一些人在应用程序加载时看到崩溃的报告,或者在用户从主菜单和应用程序中选择了一个级别后很早正在加载关卡纹理。我们发现,如果这些用户刚刚重新启动设备,他们就再也没有问题了。由于这是我们第一次看到类似这样的问题,我们将其归因于TestFlightApp正在做的事情,一些有趣的状态是它在安装后离开设备(我们与TestFlightApp谈论此事,他们从未听说过这样的事情)。
  • 如前所述,苹果已经批准了该应用程序,它在App Store上。不久之后,我们从一些iPad1用户那里得到了一些报告,称它在应用加载时或之后很快就会崩溃,就像我们在某些TestFlightApp用户看到的那样。再次与TestFlightApp用户类似,这些客户报告说重新启动通常会解决问题。但这并不是很好,因为这个问题往往会再次出现。其中一位用户向我发送了几个LowMemory ...日志文件,她在与她的iPad同步后下了电脑。有大约10个这样的文件,并且其中他们列出了我的程序在进程列表中。相反,它显示其他程序标记为(主动)或(抛弃),“最大的过程”可以是任何从MobileSafari到Kobo,但我的应用程序再次从未列出。所以,我不明白这一点,但底线似乎是这样的,至少对于这个用户来说,一些内存超过了我的应用程序不能很好运行的限制。
  • 我已经回去和TestFlightApp beta测试人员交谈,结果他确实有时会再次遇到应用崩溃,所以它不仅仅是来自TestFlightApp的一些残留。然而,对他来说,这次事故的频率远远低于这位客户。
  • 其他iPad1游戏测试人员从来没有遇到任何麻烦。他们报告说,他们每天玩游戏数小时,使用iPad和其他几款应用程序,而且很少关闭它们。同样,我从来没有碰到过我的iPod Touch第四代,它与iPad1类似,它有一个高分辨率屏幕,但只有256k RAM。

因此,这对我来说非常神秘,对于这些特定用户的iPad来说,这可能会如此不同。游戏在设备重新启动后工作很神秘,但在某些应用程序运行后(有时)游戏加载时出现问题。我的理解是,如果我的游戏需要内存,操作系统将根据需要自动关闭其他正在运行的应用程序,以便有效地将内存量恢复到刚刚重新启动的设备上可用的量。我唯一的结论是,在运行一些应用程序后,设备处于内存较少的状态,因为操作系统无法回收某些内存块或关闭某些应用程序。

不幸的是,我没有这些“行为不端”设备之一开发。我所能想到的就是尽量减少我的应用程序的内存需求,并将其发送给有问题的用户之一,并查看它是否修复了问题。然而,这似乎是一种潜在的低效方法。

有人有更好的主意吗?

+0

在任何支持多任务处理的iDevice上打开其他一些应用程序,然后运行您的游戏。这可能会复制这次事故。 – darvids0n

+0

是的,已经做到了。无法在我自己的设备上重新制作。令人沮丧。 –

回答

2

纹理加载过程中出现内存尖峰的声音是导致应用在某些设备上终止的原因。它可能会使用更少的内存之后所有的东西都被加载了,比它在初始加载结束时还好。这可以通过将事物推入虚拟内存来解释,而直接纹理加载可能会以太多分配的方式轰击RAM。我的建议将是:

  • 要与加载过程中破坏的临时数据结构更积极(release临时搭建其所有有用的值都被读出的时刻/其他东西所提取的)
  • 对于autorelease d对象,随时保持NSAutoreleasePool;如果您使用极高数量的autorelease d对象,则您甚至可能想要在一种方法中多次使用drainalloc池。
  • 这可能听起来很愚蠢......故意拖慢你的加载过程。如果您摆脱了并行负载(一次加载多个对象),或者可能会在加载线程/方法中插入手动时间延迟,这可能会给操作系统更多时间将内容推送到虚拟内存,因此看门狗不会将该应用程序检测为作为RAM猪。

编辑:一个可能的策略,以实现更慢装载:如果/当你收到内存不足警告,暂停或加载速度慢下来了几秒钟,给其他应用程序的时间来降低他们的内存使用情况,然后再继续以正常速度加载。

即使我错了(如果LowMemory...log文件显示虚拟+物理使用,因此您的应用程序甚至没有那么多),我会建议然后集成错误报告,如QuincyKit,以便您通过电子邮件发回一个回溯,当这个bug在野外遇到时崩溃的描述。

+0

所以,这是有趣的,我没有想到的东西。我不太确定你的建议可能会推到虚拟内存。我自己的数据?其他常驻应用程序的数据?但无论如何,我没有想到的是一个应用程序开始占用内存时会发生什么。操作系统应该给其他应用程序几秒钟(或任何超时)关闭自己。所以我的确可以想象,慢慢记忆的速度会慢得多。嗯... –

+0

您自己的数据和其他常驻应用程序的数据。就像桌面操作系统一样,一旦RAM开始变满,最近最少使用的内存页面将从RAM中转储到虚拟内存(交换文件)中。不确定在页面错误方面会发生什么情况,不管页面是在RAM中找不到,而是在虚拟内存中,是否触发不同类型的页面错误或根本没有。无论哪种方式,它都会让Watchdog始终强制退出高内存使用率应用程序。 – darvids0n

+0

另外,当RAM开始变满时会发生什么,每个正在运行的应用程序都会得到一个['UIApplicationDidReceiveMemoryWarningNotification'](http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIApplication_Class/Reference/Reference.html #// apple_ref/c/data/UIApplicationDidReceiveMemoryWarningNotification),它是由你的'UIApplicationDelegate'(如果你实现'applicationDidReceiveMemoryWarning:')和活动的'UIViewController'(如果你实现'didReceiveMemoryWarning')自动拾取的;有一个默认的实现太)。但你可能已经知道了。 – darvids0n