为什么我只分配7 MB内存就会收到内存警告?

mm2*_*m24 22 memory-management ios memory-warning

我正在iPod touch设备上运行我的iOS应用程序,即使总分配峰值仅为7 MB,我也会收到内存警告,如下所示(当按下游戏场景时会发生这种情况):

低记忆警告

什么我觉得奇怪的是:

  • 左峰(在时间0.00),对应于20 MB的内存分配(简介场景),尽管这并没有给出任何内存警告.

  • 中心峰(在时间35.00)对应于raughly 7 MB的所分配的存储器(游戏场景正在被推动)和DOES给存储器的警告.

如果总内存只有7 MB,我不明白为什么会收到这些警告.这是正常的吗?我怎么能避免这个?

密度峰值

查看分配密度,我们可以看到以下模式,对于我来说,在推动介绍场景的时刻(0.00)与推动游戏场景的时刻(35.00)之间没有显示出太大差异.由于密度峰值相似,我认为记忆警告是由于我无法发现的其他东西.

编辑:

我一直在遵循建议使用"活动监视器",但不幸的是我的应用程序在加载游戏场景时崩溃,只分配了30 MB的内存.这是活动监视器报告.

活动监控报告

查看报告,我可以看到总实际内存使用量总和约为105 MB.鉴于这应该参考RAM内存并且鉴于我的模型应该有256 MB的RAM,这不应该导致APP崩溃或内存泄漏问题.

我运行Leak监视器,它在我的应用程序上没有显示任何泄漏.我也杀死了所有其他应用程序.

但是,在分析报告时,我看到与我的应用程序相关的惊人的167 MB虚拟内存值.这是正常的吗?这个值意味着什么?这可能是坠机的原因吗?如何检测代码的哪些区域对此负责?

虚拟内存

我的iPod是第四代机型,容量为6.4 GB(内存),只有290 MB无内存.我不确定这是否会以某种方式影响虚拟内存分页性能.

编辑2:我也更注重SpringBoard,其虚拟内存使用量为180 MB.这是正常的吗?我发现一些问题/答案似乎表明SpringBoard负责自动释放对象(它应该是管理屏幕和主页的过程,但我不确定它是否也与内存管理有关).它是否正确?

另一个说明.我正在使用ARC.但是我不确定这对问题有多大帮助,因为没有明显的内存泄漏,XCode应该转换代码,将release/dealloc/retain调用添加到已编译的二进制文件中.

编辑3:如前所述我使用ARC和Cocos2d(2.0).我一直在玩Activity监视器.我发现如果我删除了GameCenter身份验证机制,那么Activity Monitor运行正常(新疑点:是否有其他人遇到过类似问题?GameCenter身份验证视图是否保留在某处?).但是我注意到每次我在GameScene(初始场景 - >角色选择 - >行星选择 - >角色选择 - >行星选择 - >等等 - >字符选择......)之前的各种场景中前后导航.REAL MEMORY使用量增加.过了一会儿,我开始得到内存警告,应用程序被iOS杀死.现在的问题是:

- >我是以正确的方式更换场景吗?我从各种场景中调用以下内容:

[[CCDirector sharedDirector] replaceScene: [MainMenuScene scene]];
Run Code Online (Sandbox Code Playgroud)

我有Cocos2d 2.0作为静态库,replaceScene的代码是这样的:

-(void) replaceScene: (CCScene*) scene
{
    NSAssert( scene != nil, @"Argument must be non-nil");

    NSUInteger index = [scenesStack_ count];

    sendCleanupToScene_ = YES;
    [scenesStack_ replaceObjectAtIndex:index-1 withObject:scene];
    nextScene_ = scene; // nextScene_ is a weak ref
}
Run Code Online (Sandbox Code Playgroud)

我想知道这个场景是不是得到了正确的解除分配.我验证了正在调用清理方法但是我还在CCLayer dealloc方法上添加了一个CCLOG调用并重建了静态库.结果是dealloc方法似乎没有被调用.

这是正常的吗?:d

我发现其他人也有类似的问题.我想知道它是否与保留周期和自身块有关.我真的需要花一些时间研究这个,除非从编辑3,任何人都可以告诉我我做错了什么:-)

mm2*_*m24 0

我通过在控制台中添加进程有效内存使用情况的打印来解决这个问题。通过这种方式,我可以精确测量应用程序进程使用的实际内存。事实证明,使用仪器是不精确的,因为使用的实际内存与仪器上显示的内存不匹配。

此代码可用于获取有效内存使用情况:

-(vm_size_t)report_memory
{    
    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 ) {
    } else {
        NSLog(@"Error with task_info(): %s", mach_error_string(kerr));
    }
    return info.resident_size;
}
Run Code Online (Sandbox Code Playgroud)

  • 答案是……? (6认同)