Responding to RAM availability in iOS

那年仲夏 提交于 2019-11-27 14:28:22
Steve

To get the total (maximum) physical RAM of the device use [NSProcessInfo processInfo].physicalMemory.

See Documentation.

Total physical RAM is available via sysctl(), as documented in this blog post and implemented as a nice clean API here (see the implementation of totalMemory in the corresponding .m file).

I've lifted the blog's code for convenience and posterity:

#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;
}

I don't know if Apple will approve an app that uses sysctl() in this manner. It is documented, but only for Mac OS X.

The most important think you need to know for memory management in this case is wether to use High or low res textures. The simplest way I use is to check this

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

This works for all devices so far and should be future proof, newer devices will use the high res. You might also calculate right there the aspect ratio (helps later on ipad vs iphone)

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

Don't load highres first it kills your apps load time, on my 3G most of my startup is spent loading (even the low res) textures, just test for this right at the beginning and don't touch the highres stuff.

On older devices the program will die without warning due to big textures, may have something to do with de debugger not being able to trap the video memory consumption and dying itself.

For greater optimizations consider tinting you mipmaps to check the lowest texture size that's actually being used (only if your using 3D objects).

Forget the video RAM size issue, memory is actually shared, so you're competing for system memory, on older devices you had a MB limit for use, but it's still system memory.

About memory management, there are many ways to do it, the simplest should be mark the textures that are loaded, and textures that are needed, when a memory warning comes, dump the textures that are loaded but not needed...

As far as I know the 3 most important things one can do is -

  1. implement - (void)didReceiveMemoryWarning and respond when iOS sends warnings 1 & 2.
  2. Profile code in Instruments trying to find leaks & better mem optimum ways of implementation.
  3. Detect device types & maybe use that info.
  4. Use some form of texture compressions like PVRTC to save space.

I think you are doing most of them. The thing is one does not even know accurately how much RAM iOS devices has. Apple does not publish tech specs for iOS devices.

Also, it cannot be assumed that only after say 100mb of consumption you will get a mem warning. The warnings that iOS gives varies depending on the current state of the device & what other apps are running & how much mem they are consuming. So it gets tricky.

I can suggest 2 must read sections - Best Practices for Working with Texture Data and Tuning Your OpenGL ES Application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!