Memory management '中的内存不足;其他流程';使用中比较Xcode iOS9

Memory management '中的内存不足;其他流程';使用中比较Xcode iOS9,memory-management,parse-platform,sprite-kit,ios9,instruments,Memory Management,Parse Platform,Sprite Kit,Ios9,Instruments,我的应用程序在内存为0.5GB的设备上崩溃。然而,在Xcode中评测内存使用情况——它很少超过140MB。我用仪器检查过泄漏,但没有一个是重要的 然而,当我运行我的应用程序时,“其他进程”使用的内存总是非常高。这是启动后的静止状态: 在我的代码中,我在循环的每个周期中增加了1秒的延迟,并发现在每个循环中,“其他进程”会使每个对象的内存使用量增加约3MB,直到在0.5GB设备上,内存耗尽并崩溃 表明这些是使用该内存的其他应用程序,但我关闭了所有其他应用程序,使用情况与我的循环代码直接相关 在我

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

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

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

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

在我的应用程序中实际运行的其他进程中可能会使用哪些内存?为什么我的“其他进程”占用了这么多内存

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

self drawRelationships:[_batches objectAtIndex:_index] forMini:_playerMini];
是一个任务,因此是异步的。我将数组划分为更小的批,以便在绘制每个批时可以看到增量内存使用情况。如果我试图一次画出全部,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];
        }
    }
}
-(void)drawNewRelationships
{
_批次=[NSMutableArray];
_指数=0;
[\u playerMini fetchinbackgroundithblock:^(PFObject*object,NSError*error){
[ParseQuery GetNewRelationshipFormini:_playerminicurrent:_miniRows.relationshipId with block:^(NSMutableArray*newRelationships){
_批次=[self-BatchArray:3 fromArray:newRelationships];
_指数=0;
[自退税];
}];
}];
}
-(无效)退税
{
if([\u批次对象索引:\u索引]){
[自绘制关系:[[u batches objectAtIndex:[u index]forMini:[u playerMini];
_索引++;
如果(_索引<[[u批次计数]){
[self-performSelector:@selector(牵引杆)with object:nil afterDelay:1];
}
}
}
该节点包含其他数据(几个数组、自定义对象),我已尝试在删除所有数据的情况下运行该应用程序。我试着在主线程和后台线程上运行。我尝试过使用BFTask异步地做事情。我尝试过的每件事都以同样的行为结束——创建这些SKNode对象会消耗“其他进程”中的内存,直到在内存不足的设备上崩溃

可能值得注意的是,这种行为从iOS9开始才出现

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

更新

我试过运行Sprite Kit示例应用程序,甚至在其他进程启动时也会使用~550MB。这可能是一个主要的精灵套件错误吗


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


我还发现了一篇非常好的博文:关于减少应用程序的内存占用。如果你试图优化,值得一读

我想为那些不一定使用SpriteKit,但面临其他进程占用越来越多内存问题的人提供一个解决方案,这意味着存在泄漏。这是迄今为止我发现的调试“其他进程”中泄漏的最好方法

  • 打开仪器,选择活动监视器
  • 复制应用程序中的步骤,查看哪个进程负责泄漏。例如,如果它是mediaserverd,则可能存在围绕编码/解码或与媒体相关的泄漏,因此释放缓冲区或释放解压会话之类的事情可能无法按计划工作
  • 现在,您已经知道了要查找的位置,打开Xcode并使用调试内存图工具,查找潜在的泄漏实例,您应该可以看到所有关于它的强引用。对于我自己来说,在objective-c++中做了很多工作,结果发现经常缺少AutoreleasePool

  • 你能用实际的代码把你的段落扩展到“给我一个关于我在做什么的想法…”的开头吗?这可能会提供更多的洞察力。您也可以尝试在循环过程中释放内存。@AaronBrager好的-我将查看发布Objective-c的自动释放池。。。我需要添加很多代码来提供清晰的图片,我不确定它是否相关,因为这个问题也发生在示例项目中。我希望会有一个更自上而下的solution@AaronBrager好的,我添加了一些代码。我在autoreleasepools上查看了这个:但不确定在哪里可以使用它。我尝试在autoreleasepool中添加节点,但另一个进程内存仍在消耗。根据代码很难理解您在做什么(您调用的某些方法丢失)。但是看起来您有很多代码专门用于维护完成任务的顺序,并且您可能在这个过程中建立了一个非常大的堆栈。考虑使用<代码> NSO操作队列> />代码重写这些东西。您可以将每个单独的工作块添加为<代码> NSBROW操作< /代码>,节流阀一次完成多少,并在工作完成后得到通知。