使用情况比较Xcode iOS9中“其他进程”中的内存用尽

问题描述 投票:7回答:2

我的应用在具有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

memory-management parse-platform sprite-kit ios9 instruments
2个回答
1
投票

嗯,事实证明这是一个相当具体的问题。分配给其他进程的内存实际上是我的应用程序泄漏的内存。当我拉平一个有很多子节点的节点时发生了这种情况,但是并没有使NSDictionary包含对所有预拉平节点的引用。出于某种原因,此内存泄漏在配置文件时未显示。

[我还发现了一个很好的博客文章:http://battleofbrothers.com/sirryan/memory-usage-in-sprite-kit关于减少应用程序的内存占用。如果您要尝试优化,值得一读。


0
投票

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

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