我正在测试我的iOS游戏,并注意到它占用了多少内存与它应该占用的想法之间的差异。最终我将问题缩小到纹理,占用的内存比我认为应该占用的内存多33%。
例如,我认为256x256未压缩的32位纹理应该采用256 * 256 * 4字节= 256k。但是,我会注意到应用程序的内存在分配256x256纹理时增长了340k。好像设备分配了足够的内存来存储纹理及其所有mipmap,但我没有使用mip贴图或以任何方式询问空间。
这个额外的记忆突出,因为它只会发生在某些设备上。在iPod Touch 4上测试游戏时,我注意到了额外的内存。但是,在iPhone 3GS,iPod 3G或iPad 1上没有出现这个问题。
设备上的操作系统版本是:
iPod 3G - iOS 3.1.2(7D11) iPhone 3GS - iOS 4.3.5(8L1) iPod 4 - iOS 4.2.1(8C148) iPad - iOS 4.3(8F190)
修改
这里有更多信息。我像这样测量应用程序的内存
int PlatformIOS::GetProcessMemUsage()
{
task_basic_info info;
mach_msg_type_number_t size = sizeof( info );
kern_return_t kerr = task_info( mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size );
if ( kerr == KERN_SUCCESS )
return info.resident_size;
return 0;
}
这将返回您在Real Mem的Insturments程序中看到的相同值。它实际上非常有用。
以下是我分配纹理的方法:
bool GL3DTextureDataPiece::CreateTextureSurface(X3DInterfaceImpl *theInterface, int theWidth, int theHeight, PixelFormat theFormat, RefCount *thePalette, bool generateMipMap)
{
glGenTextures(1,&mTexture);
theInterface->SetCurTexture(this);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,mLinearFilter?GL_LINEAR:GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,mLinearFilter?GL_LINEAR:GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, theWidth, theHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
return true;
}
这都是非常基本的东西。导致我首先发现内存问题的唯一原因是不同设备之间的差异。事实上,总应用程序内存和资源内存之间的差异(我自己跟踪图像和声音记忆)让我调查发现这个错误。
答案 0 :(得分:8)
我已经找到了解决方法,所以我将回答我自己的问题。但我想我会发布这个,因为它似乎是一个需要注意的重要信息。
其他人发现了这个错误。例如,见这里:
http://www.cocos2d-iphone.org/forum/topic/29121
好消息是这个bug有一个解决方法。解决方法是仅使用非幂2(npot)纹理。 NPOT纹理不能被mip映射,因此iOS不会尝试分配额外的mip映射内存(至少这是它工作原理的理论。)
幸运的是,这在我的引擎中很容易做到,因为它已经将图像分成多个纹理,如果有必要,只需要适应2次幂纹理而不需要使用太多内存。因此,我只是将我的代码调整为不分割图像以适应2次幂纹理,并进一步强制任何在两个维度上都是2的幂的图像加载到比1个像素大的纹理中。宽度必要。因此,举例来说,我会将256x256图像放入257x256纹理中。
这消除了33%的额外内存增长。
请注意,较旧的设备(如iPod 3G)无法执行npot纹理,因此在执行此修复之前检查是否可行是很重要的。要检查这一点,您可以查询GL_APPLE_texture_2D_limited_npot扩展名。另外,在添加此额外像素时,请注意不要超过最大纹理大小,以强制纹理为npot。
答案 1 :(得分:4)
确保您没有自动生成mipmap: http://www.opengl.org/wiki/Texture#Automatic_mipmap_generation
mipmap链将占用33%的额外空间,因为mipmap链接近1/3额外 - 请参阅下面的系列,其中t是原始纹理的大小: = t + t / 4 + t / 16 + t / 64等......
编辑:
请注意,发布用于衡量应用内存的方法以及用于创建纹理的方法也很有帮助。
可能是您使用的方法总是创建一个额外的33%缓冲区,或者您可能只是错误地调用该方法。