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

时间:2013-09-03 10:35:12

标签: ios memory-management memory-warning

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

low memory warning

我觉得奇怪是:

  • 左峰(在时间0.00)对应于20 MB的内存分配(简介场景),尽管如此,不会给出任何内存警告。

  • 中央峰值(时间35.00)对应于分配的7 MB内存(正在推动游戏场景)并且会发出内存警告。

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

Density peaks

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

编辑:

我一直在遵循使用“活动监视器”的建议,但遗憾的是,当加载游戏场景仅分配了30 MB的内存时,我的应用程序崩溃了。这是活动监视器报告。

Activity monitor report

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

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

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

Virtual memory

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

编辑2:我还看了更多SpringBoard,其虚拟内存使用量为180 MB。这是正常的吗?我发现一些questions/answers似乎暗示SpringBoard负责自动释放对象(它应该是管理屏幕和主页的过程,但我不确定它是否也与内存管理有关)。这是对的吗?

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

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

- &GT;我是否以正确的方式更换场景?我从各种场景中拨打以下电话:

[[CCDirector sharedDirector] replaceScene: [MainMenuScene scene]];

我有 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
}

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

这是正常的吗? :d

我发现其他人有similar issues。我想知道它是否与retain cycles and self blocks.有关我真的需要花一些时间研究这个,除非从编辑3,任何人都可以告诉我我做错了什么: - )

2 个答案:

答案 0 :(得分:3)

所有应用和流程共享的所有内存容量都在iOS中运行。因此,其他应用程序可以使用大量内存,您的应用程序也会收到内存警告。你会收到内存警告,直到它还不够。

要了解应用中内存实际发生的情况,您应该

  1. 使用泄漏配置您的应用程序(ARC不保证您没有泄漏,即自我捕获问题)。

  2. 使用快照分析(此处简述http://bentrengrove.com/blog/2013/4/26/heapshot-analysis

  3. 并查看此帖关于记忆和放大器iOS中的虚拟内存:http://liam.flookes.com/wp/2012/05/03/finding-ios-memory/

答案 1 :(得分:0)

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

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

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