我正在使用适用于iOS的Cocos2D开发游戏。
有些菜单之类的场景和主要游戏场景。在主场景中只有三个动态对象。这些物体定期相互射击(直到这些物体被杀死或移出场景)。
现在的问题是:游戏不断耗尽记忆力。我想知道我做错了什么。
没有明显的泄漏,如过度保留的物体。场景得到dealloc
,对象从父母中移除并清理,动画停止等等。
无论如何,记忆一直在某个地方。我正在使用以下代码
+ (void) reportMemory
{
struct 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)
NSLog(@"Memory in use (in Kbytes): %f", info.resident_size / 1024.0);
else
NSLog(@"Error with task_info(): %s", mach_error_string(kerr));
}
查找每次开始场景时消耗的内存量。报告的数字总是比前一个更大。
我尝试使用分配探查器但老实说我无法弄清楚任何有用的东西。我看到总的生存字节基本相同,但是进程不断地分配和释放一些东西。
你建议我看一下什么?基本上,我正在寻求如何在我的情况下调试内存操作的建议。
编辑(有什么帮助我):
原来我打开了NSZombieEnabled。基本上,它是恒定内存消耗增加的主要因素。可以在@coneybeare answer
中找到一些有用的信息和提示第二个最有用的事情是使用@Jack建议的仪器(泄漏和分配)。它帮助我找到了几个微妙的泄漏。
答案 0 :(得分:5)
乐器绝对是你的朋友,是一种吃掉记忆然后你能看到它的东西。
您应该使用的第一件事是泄漏工具(不是分配工具),它将通过每隔X秒采样一次内存来显示泄漏。
如果单击特定的已识别泄漏,则可以看到
如果这还不够,通过选择分配乐器,左侧会有一个标有标记堆的按钮。此按钮每次单击时都会创建堆的快照,并且它能够显示确切的差异,以便您能够查看是否存在已分配的内存,并且在两个时刻之间永远不会释放内存。是的。
有了这些,我总能找到任何与记忆相关的问题!
答案 1 :(得分:3)
我首先看一下纹理缓存,如下所示:
[[CCTextureCache sharedTextureCache] dumpCachedTextureInfo];
在每个场景的开头做这个。纹理可以是真正的记忆猪。可能你在某种程度上坚持一些纹理(一种快速的方法是通过spriteFrames也在某个地方的缓存中),或者保留的引用可能在你的数据模型中某处。这是我的#if DEBUG memoryWarning委托:
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
CCLOG(@"AppDelegate<applicationDidReceiveMemoryWarning> : before purging all caches");
[[CCTextureCache sharedTextureCache] dumpCachedTextureInfo];
[[CCSpriteFrameCache sharedSpriteFrameCache] removeUnusedSpriteFrames];
[[CCDirector sharedDirector] purgeCachedData];
CCLOG(@"AppDelegate<applicationDidReceiveMemoryWarning> : after purging all caches");
[[CCTextureCache sharedTextureCache] dumpCachedTextureInfo];
}
答案 2 :(得分:2)
确保您没有在Cocos层面保留任何物品;除非Cocos拥有唯一的控制权和所有权,否则Cocos内置的清理物体的方法并不总是有效;如果您将Sprite或Layers存储为保留的iVar,将其引用次数增加到正常的Cocos所有权之外,那么它们可能无法按预期进行清理。出于这个原因,我在保持指向Cocos对象的指针时总是使用assign
属性。