Apple SpriteKit物理内存泄漏与解决方案

最近在创建游戏时,我注意到我正在缓慢地泄漏内存……每2分钟大约1到1.5MB。 开始我长时间的潜入我的代码以查找罪魁祸首。 我能够将它从概要分析和多个注释掉的代码部分中缩小到一行代码。

testSprite.physicsBody = SKPhysicsBody.init(rectangleOf:CGSize(宽度:200,高度:20))

什么? 什至这是怎么可能的,我所做的只是为一个小方形精灵创建一个PhysicsBody。 我创建了一个新的空白项目,并使用了相同的封闭方法…

发生相同的内存泄漏。 如果我注释掉创建physicsBody的话,就不会发生内存泄漏。 这让我回想起我第一次遇到SpriteKit的内存泄漏的问题,该错误是“ view.showsPhysics = true”,但是这次我没有打开内存,所以我有些困惑。 我必须更深入地剖析配置文件,以便深入了解这一点。 运行分配工具,我可以标记时间范围或“ Generations”,以查看在一段时间内有多少内存泄漏。 请记住,在此之前我所做的所有事情都是在屏幕上轻按一次以创建单个testSprite,而在配置过程中的其余时间中从未触摸过屏幕。 内存泄漏无休止地增长-根本没有任何其他输入。 从我已经注意到的情况来看,取消此设置所需要做的就是创建任何类型的物理体。 通过下面的时间戳,您可以看到从C代到D代,我们在大约1分钟20秒左右的时间内增长了733KiB。

如果我们深入研究C一代的时间框架,我们可以看到导致错误的原因。

罪魁祸首是CAMetalDrawable和_NSArrayM(也是金属函数)。 潜水更深……

深入研究CAMetalDrawable,我们看到它正在创建一堆这64字节的分配。 进入这些分配之一可以发现……

有很多东西在此调用“保留/释放”,但是其中一个特别称为“保留”,但是从来没有附带的“释放”,您可以看到它是中间的,“ Jet”下的Response — jet_context_Metal:create_texture_from_Metal_D…等等。因此有了ARC从不释放这些分配,并且将这些分配保留在内存中。

好的-太好了,所以我发现了造成这种情况的原因,这并不是我在做的任何事情,但是由于没有在Metal中创建新的游戏引擎,因此我似乎无法解决该问题既不放弃SpriteKit,也不接受我的游戏内存泄漏很小的游戏。 但是a,我偶然发现了来自苹果公司的有趣的技术质量检查。 “如何为SpriteKit和SceneKit指定渲染器?”解决方案是将Metal完全放弃用于OpenGL。 尽管我确信Metal可以为大型3D游戏提供许多好处,但我的简单2D游戏确实不需要额外的推动力。 说了这么多,我要做的就是在info.plist文件中将布尔类型的“ PrefersOpenGL”添加为= YES

和BOOM! 稳定的内存使用。 至少要等到下一个。 我已将此问题提交给了bug跟踪程序供Apple审查,希望它很快就会修复。