SpriteKit Tileset 内存泄漏

Posted

技术标签:

【中文标题】SpriteKit Tileset 内存泄漏【英文标题】:SpriteKit Tileset Memory Leak 【发布时间】:2019-03-09 14:26:02 【问题描述】:

我正在尝试使用 SpriteKit 创建 2d 平台游戏。游戏包含 21 个关卡,这意味着 21 个场景和 21 个图块集。 每个场景包含几个 tilenodes,所有这些 tilenodes 只使用 1 个tileset。 在某些时候,我发现我的游戏消耗了将近 2GB 的内存,并且有时由于内存问题而被终止。

我开始使用工具调查这种内存泄漏的原因。我发现了 4 个泄漏,显示在附加的屏幕截图中。 负责的库是 javascriptCore,我不知道这到底是什么意思。

因此,我继续调查并尝试从项目中删除代码块和资产,以了解发生了什么。

最后我的项目包含:

    GameViewController 与 XCode 模板中的 GameViewController 完全一样。 SKScene 的空子类 1 场景 21 瓦片集

GameViewController 的代码:

class GameViewController: UIViewController 

override func viewDidLoad() 
    super.viewDidLoad()
    if let scene = GKScene(fileNamed: "GameScene") 
        if let sceneNode = scene.rootNode as! SKScene? 
            sceneNode.scaleMode = .aspectFill
            if let view = self.view as! SKView? 
                view.presentScene(sceneNode)
                view.ignoresSiblingOrder = true
            
        
    



override var shouldAutorotate: Bool 
    return true



override var supportedInterfaceOrientations: UIInterfaceOrientationMask 
    if UIDevice.current.userInterfaceIdiom == .phone 
        return .allButUpsideDown
     else 
        return .all
    



override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()
    // Release any cached data, images, etc that aren't in use.



override var prefersStatusBarHidden: Bool 
    return true

因此,没有可能导致泄漏的代码,游戏仍然会在峰值时消耗 2GB。 并且只有当我从项目中删除所有图块集时,除了关卡所需的图块集 - 内存消耗变得正常,例如 ~200mb。

我的猜测是 SpriteKit 将所有图块集加载到内存中,尽管场景的所有图块节点仅使用 1 个图块集。

此外,如果我将瓦片集放回项目并从场景中删除所有瓦片节点,游戏效果会很好。

我的问题是如何妥善处理这种情况?

谢谢!

Update1:​​内存图已附加 Update2:提供GameViewController代码

【问题讨论】:

你可以调试内存图并追踪那些紫色的'!'。它会告诉你泄漏的来源。 我也这样做了,图表显示对我没有任何用处。我附上了图表截图。 没有代码,你的问题相当于鼻烟。我们不介意读者。 你应该摆脱所有那些粉紫色的“!”。有时,就像错过了weak。有时您以不完美的方式调用系统函数。但首先尝试删除所有那些! SKTileMapNode 和它的周边功能非常有问题。我对你遇到这个问题并不感到惊讶。我有第一手经验,我可以告诉你,我建议远离 SpriteKit 的这一部分。您将更轻松地编写所有自己的代码来代替 SKTileMapNodes(以及周围的功能)。 【参考方案1】:

试试这个:

打开Info.plist文件,添加新行,

键:“首选OpenGL” 类型:“布尔” 值:“是”

【讨论】:

SpriteKit 现在默认为 Metal 模式,切换回 OpenGL 兼容模式可能对某些调试目的有用,但它不是出货产品中的解决方案。【参考方案2】:

我找到了这个问题的原因。我所有的图块集都在不同的文件中,每个图块集都有自己的 sks 文件。当我将所有图块集移动到一个 sks 文件中时,问题就消失了。我假设在某些时候游戏会尝试为每个 sks 文件加载所有现有的图块集,并占用太多内存。

【讨论】:

以上是关于SpriteKit Tileset 内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

分析 ThreadLocal 内存泄漏问题

内存泄漏和内存溢出的区别

Android开发常见的Activity中内存泄漏及解决办法

OpenGL VBO 会泄漏内存吗?

PowerPoint 2010 内存泄漏?

Javascript的内存泄漏分析