如何找出Cocos2d中的内存消耗量

时间:2012-06-04 13:49:37

标签: ios memory-leaks cocos2d-iphone profiling xcode4.2

我正在使用适用于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建议的仪器(泄漏和分配)。它帮助我找到了几个微妙的泄漏。

3 个答案:

答案 0 :(得分:5)

乐器绝对是你的朋友,是一种吃掉记忆然后你能看到它的东西。

您应该使用的第一件事是泄漏工具(不是分配工具),它将通过每隔X秒采样一次内存来显示泄漏。

如果单击特定的已识别泄漏,则可以看到

  • A 负责的调用链中发现泄漏
  • 点击 B 中的小箭头,您可以看到内存泄漏的确切生存进展(例如,当它已经被malloc' d,保留,释放等等)

Leaks Xcode

如果这还不够,通过选择分配乐器,左侧会有一个标有标记堆的按钮。此按钮每次单击时都会创建堆的快照,并且它能够显示确切的差异,以便您能够查看是否存在已分配的内存,并且在两个时刻之间永远不会释放内存。是的。

enter image description here

有了这些,我总能找到任何与记忆相关的问题!

答案 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属性。