在iOS中响应RAM的可用性

我有一个纹理很重的OpenGL游戏,我想根据这个设备有多lessRAM来调整。 我在iPhone 4或iPad2上的最高分辨率纹理工作正常,但较早的设备在加载纹理的过程中崩溃。 我有这些纹理的低分辨率的版本,但我需要知道什么时候使用它们。

我目前的策略是检测特定的旧设备(3GS有一个低分辨率的屏幕,iPad没有相机),然后只加载高分辨率的纹理IPad2及以上和iPhone 4及以上 – 我想我需要为iPod touch做一些事情。 但我更愿意使用特征检测而不是硬编码设备模型,因为模型检测对于将来对API和硬件的更改是脆弱的。

我正在考虑的另一种可能性是首先加载高分辨率的纹理,然后下降,并取代低分辨率的时候,我得到一个低内存警告。 不过,我不确定我会有机会回应。 我注意到,在debugging控制台上出现任何通知之前,应用程序经常死亡。

如何检测我正在运行的设备是否没有足够的RAM来加载我的纹理的高分辨率版本?

退一步来说,是否还有其他一些适用于OpenGL纹理内存的自适应技术?

笔记:

  1. 我已经search了关于可用RAM检测的答案,但他们都基本上build议分析内存使用情况,并消除浪费(最大限度地减less临时对象和所有这一切)。 我已经做了尽可能多的事情,而且我也不可能将高分辨率的纹理压缩到较旧的设备上。

  2. PVRTC不是一个选项。 纹理包含片段着色器要使用的数据,并且必须以无损格式存储。

要获得设备的总(最大)物理RAM,请使用[NSProcessInfo processInfo].physicalMemory

见文档 。

总体物理内存可通过sysctl() ,如本博文中所述,并在此处作为一个很好的干净API实现(请参阅相应.m文件中的totalMemory实现)。

为了方便和后代,我已经提出了博客的代码:

 #include <sys/sysctl.h> size_t phys_mem() { int mib[] = { CTL_HW, HW_PHYSMEM }; size_t mem; size_t len = sizeof(mem); sysctl(mib, 2, &mem, &len, NULL, 0); return mem; } 

我不知道苹果是否会以这种方式批准使用sysctl()的应用程序。 这是logging,但只适用于Mac OS X.

在这种情况下,你需要知道的最重要的内存pipe理是使用高分辨率或低分辨率纹理。 我使用的最简单的方法是检查这个

 CGFloat scale = [[UIScreen mainScreen] scale]; if ((scale > 1.0) || (self.view.frame.size.width > 320)) { highRes = TRUE; } 

这到目前为止所有设备的工作,应该是未来的certificate,新设备将使用高分辨率。 你也可以计算出那里的宽高比(稍后帮ipad vs iphone)

 aspect = self.view.frame.size.width/self.view.frame.size.width 

不要首先加载高分辨率,它会杀死你的应用程序加载时间,在我的3G上,我的大部分启动都花费在加载(甚至是低分辨率)的纹理,只是在开始时testing这个权利,不要触及高分辨率的东西。

在较老的设备上,程序会由于纹理太大而没有任何警告地死掉,可能与dedebugging器无法捕捉video内存消耗和死亡本身有关。

为了获得更多的优化,可以考虑使用mipmap来检查实际使用的最小纹理大小(仅当使用3D对象时)。

忘记videoRAM大小的问题,内存实际上是共享的,所以你争夺系统内存,在较旧的设备上,你有一个MB使用限制,但它仍然是系统内存。

关于内存pipe理,有很多方法可以做到这一点,最简单的应该是标记加载的纹理和需要的纹理,当内存警告来临时,转储加载但不需要的纹理…

据我所知,人们能做的三件最重要的事情是 –

  1. 实施- (void)didReceiveMemoryWarning并在iOS发送警告1和2时作出响应。
  2. 在仪器中的configuration文件代码试图find泄漏和更好的mem最佳的实现方式。
  3. 检测设备types,也许使用该信息。
  4. 使用某种forms的纹理压缩如PVRTC来节省空间。

我认为你正在做的大部分。 事情是一个甚至不知道iOS设备有多less内存。 苹果公司不会发布iOS设备的技术规格。

另外,不能认为只有在说100mb的消费之后,你才会得到一个mem警告。 iOS提供的警告取决于设备的当前状态以及运行的其他应用程序以及它们消耗多less内存。 所以它变得棘手。

我可以build议2必须阅读部分 – 处理纹理数据和调整OpenGL ES应用程序的 最佳实践

Interesting Posts