我的应用在具有0.5GB内存的设备上崩溃。但是,在Xcode中分析内存使用情况-它很少超过140MB。我已经使用过仪器来检查泄漏,但没有任何重要的泄漏。
但是,当我运行我的应用程序时,“其他进程”使用的内存始终很高。启动后是静止状态:
我在代码的每个循环中增加了1秒的延迟,发现在每个循环中,“其他进程”使每个对象的内存使用量增加约3MB,直到在0.5GB的设备上耗尽并崩溃为止。
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的主要错误吗?
嗯,事实证明这是一个相当具体的问题。分配给其他进程的内存实际上是我的应用程序泄漏的内存。当我拉平一个有很多子节点的节点时发生了这种情况,但是并没有使NSDictionary包含对所有预拉平节点的引用。出于某种原因,此内存泄漏在配置文件时未显示。
[我还发现了一个很好的博客文章:http://battleofbrothers.com/sirryan/memory-usage-in-sprite-kit关于减少应用程序的内存占用。如果您要尝试优化,值得一读。
我想为不一定使用SpriteKit的人提供解决方案,但是遇到其他进程占用越来越多的内存的问题-这意味着存在泄漏。到目前为止,这是我发现的调试“其他进程”中泄漏的最佳方法。