22

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

内存不足警告

觉得奇怪的是:

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

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

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

密度峰值

查看分配密度,我们可以看到以下模式,(对我而言)在推送介绍场景的时刻 (0.00) 和推送游戏场景的时刻 (35.00) 之间没有太大区别。由于密度峰值相似,我会假设内存警告是由于我无法发现的其他原因造成的

编辑:

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

活动监控报告

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

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

但是,分析报告后,我发现与我的应用程序相关联的虚拟内存值达到了惊人的167 MB。这是正常的吗?这个值是什么意思?这可能是崩溃的原因吗?如何检测我的代码的哪些区域对此负责?

虚拟内存

我的 iPod 是第 4 代机型,容量(内存)为 6.4 GB,只有 290 MB 可用内存。我不确定这是否会影响虚拟内存分页性能。

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

另一个注意事项。我正在使用 ARC。但是我不确定这与问题有多大关系,因为没有明显的内存泄漏,XCode 应该将添加 release/dealloc/retain 调用的代码转换为编译的二进制文件。

编辑 3:如前所述,我使用的是 ARC 和 Cocos2d (2.0)。我一直在玩活动监视器。我发现如果我删除了 GameCenter 身份验证机制,那么 Activity Monitor 运行良好(新的疑问:其他人有类似的问题吗?GameCenter 身份验证视图是否保留在某个地方?)。但是我注意到,每次我在 GameScene 之前的各个场景之间来回导航时(初始场景 -> 角色选择 -> 星球选择 -> 角色选择 -> 星球选择 -> 等等.. -> 角色选择..)REAL MEMORY 使用量增加。过了一会儿,我开始收到内存警告,并且应用程序被 iOS 杀死。现在的问题是:

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

[[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

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

4

2 回答 2

3

通过在 iOS 中运行的所有应用程序和进程共享的所有内存容量。因此,其他应用程序可能会使用大量内存,并且您的应用程序也会收到内存警告。您将收到内存警告,直到它不够为止。

要了解应用程序中的内存实际发生了什么,您应该

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

  2. 使用 heapshot 分析(这里简短描述http://bentrengrove.com/blog/2013/4/26/heapshot-analysis

并查看这篇关于 iOS 中内存和虚拟内存的帖子:http: //liam.flookes.com/wp/2012/05/03/finding-ios-memory/

于 2013-09-04T06:48:57.770 回答
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;
}
于 2014-08-04T23:33:03.743 回答