用法比较Xcode iOS9中的“其他进程”中内存不足

时间:2015-10-26 15:27:41

标签: memory-management parse-platform sprite-kit ios9 instruments

我的应用程序在具有0.5GB内存的设备上崩溃。但是,在Xcode中分析内存使用情况 - 它很少超过140MB。我用过仪器来检查泄漏,没有一个是重要的。

然而,当我运行我的应用程序时,“其他进程”使用的内存总是非常高。这是发射后的静止状态:

enter image description here

我在代码的循环的每个循环中添加了1秒的延迟,并发现在每个循环中,“其他进程”每个对象增加大约3MB的内存使用量,直到在0.5GB设备上,它耗尽并且崩溃。

enter image description here

This question表明这些是使用该内存的其他应用程序,但我关闭了所有其他应用程序,其使用情况与我的循环代码直接相关。

在我的应用程序中实际运行的其他进程中可能有什么内存?为什么我的“其他进程”耗尽了这么多内存?

为了了解我正在做什么,我从Parse中提取数据,然后遍历返回的每个对象并从数据中创建SKNode子类对象。我将此节点添加到数组(供参考)和场景。这是我在主线程上做的代码,添加了延迟。注意:

self drawRelationships:[_batches objectAtIndex:_index] forMini:_playerMini];

是BFTask还是如此异步。而且我将数组分成更小的批次,因此我可以看到增量内存使用量,因为每个批次都被绘制。如果我试图立即绘制整个批次,OOM会立即发生......

- (void)drawNewRelationships
{
    _batches = [NSMutableArray array];
    _index = 0;

    [_playerMini fetchInBackgroundWithBlock:^(PFObject *object, NSError *error) {
        [ParseQuery getNewRelationshipsForMini:_playerMini current:_miniRows.relationshipIds withBlock:^(NSMutableArray *newRelationships) {
            _batches = [self batchArrays:3 fromArray:newRelationships];
            _index = 0;
            [self drawBatches];
        }];
    }];
}

- (void)drawBatches
{
    if ([_batches objectAtIndex:_index]) {
        [self drawRelationships:[_batches objectAtIndex:_index] forMini:_playerMini];
        _index++;
        if (_index < [_batches count]) {
            [self performSelector:@selector(drawBatches) withObject:nil afterDelay:1];
        }
    }
}

该节点包含其他数据(几个数组,自定义对象),我尝试在删除所有数据的情况下运行应用程序。我试过在主线程和后台线程上运行。我尝试过使用BFTask来异步处理事情。我尝试的所有内容都以相同的行为结束 - 创建这些SKNode对象会在“其他进程”中占用内存,直到在低内存设备上崩溃。

值得注意的是,这种行为自iOS9以来才开始发生。

基本上,什么可以在“其他进程”中使用所有这些内存以及如何释放它?

更新

我已经尝试运行Sprite Kit示例应用程序,甚至在启动时在其他进程中使用~550MB。这可能是一个主要的Sprite Kit错误吗?

enter image description here

2 个答案:

答案 0 :(得分:0)

事实证明这是一个相当具体的问题。分配给其他进程的内存实际上是从我的应用程序中泄漏的内存。它发生在我用一个有很多孩子的节点展平时,但没有一个NSDictionary包含对所有预展平节点的引用。出于某种原因,这个内存泄漏在分析时并没有显示出来。

我还发现了一篇非常好的博文:http://battleofbrothers.com/sirryan/memory-usage-in-sprite-kit,用于减少应用的内存占用。值得一读,如果您正在尝试优化。

答案 1 :(得分:0)

我想为不一定使用SpriteKit的人提供解决方案,但是遇到其他进程占用越来越多的内存的问题-这意味着存在泄漏。到目前为止,这是我发现的调试“其他进程”中泄漏的最佳方法。

  1. 打开“工具”,选择“活动监视器”
  2. 在您的应用程序中重现步骤,查看哪个进程正在为泄漏获取所有权。例如,如果是mediaserverd,则可能是围绕编码/解码或某些媒体相关的泄漏,因此释放缓冲区或释放解压缩会话之类的事情可能无法按计划进行。
  3. 现在,您已经知道了在哪里查看,打开Xcode并使用“调试内存图”工具,并寻找潜在的泄漏实例,您应该会看到所有针对它的强引用。对于我自己在Objective-C ++中工作很多,结果常常是缺少自动释放池。