Javascript 什么';这是摧毁移相器实例的正确方法。游戏?

Javascript 什么';这是摧毁移相器实例的正确方法。游戏?,javascript,phaser-framework,Javascript,Phaser Framework,在创建然后销毁Phaser.Game实例的小案例中,似乎存在内存泄漏。下面是一个完整的工作示例:单击按钮创建实例,再次单击以销毁它。反复单击该按钮会导致内存使用量无限制地增长。在移相器的生命周期中,我是否缺少一些我应该做的事情 我将此作为代码片段而不是JSFIDLE发布,因为您需要查看内存分析器或类似的工具来查看问题,因此JSFIDLE会使问题复杂化 <!doctype html> <html> <head> <meta charset="UTF-8"/

在创建然后销毁Phaser.Game实例的小案例中,似乎存在内存泄漏。下面是一个完整的工作示例:单击按钮创建实例,再次单击以销毁它。反复单击该按钮会导致内存使用量无限制地增长。在移相器的生命周期中,我是否缺少一些我应该做的事情

我将此作为代码片段而不是JSFIDLE发布,因为您需要查看内存分析器或类似的工具来查看问题,因此JSFIDLE会使问题复杂化

<!doctype html>
<html>
<head>
<meta charset="UTF-8"/>
<title>test</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/phaser-ce/2.8.1/phaser.js">
</script>
</head>
<body>
   <button id="button">Click</button>
   <div id="canvas"></div>
   <script>
      window.onload = function() {
         var d, n, game;

         d = document.getElementById('button');
         n = document.getElementById('canvas');

         function preload() {
         }
         function create() {
         }
         function update() {
         }
         function handler() {
            if(game) {
                    game.destroy();
                    game = null;
            } else {
                    game = new Phaser.Game(800, 600, Phaser.AUTO, n, {
                            preload:        preload,
                            create:         create,
                            update:         update
                    });
            }
         }
         d.onclick = handler;
      };
   </script>
</body>
</html>

测试
点击
window.onload=函数(){
变量d,n,对策;
d=document.getElementById('button');
n=document.getElementById('canvas');
函数预加载(){
}
函数create(){
}
函数更新(){
}
函数处理程序(){
如果(游戏){
游戏。破坏();
game=null;
}否则{
游戏=新的移相器游戏(800600,移相器自动,n{
预加载:预加载,
创建:创建,
更新:更新
});
}
}
d、 onclick=handler;
};
回答(至少部分)我自己的问题,问题在Phaser.CanvasPool中。每当创建一个新的Phaser实例时,就会创建一个新的画布并将其添加到池中。销毁实例不会从池中删除画布或将其标记为可供重用

在调用game.destroy()之后,您可以通过设置Phaser.CanvasPool.pool=[]等粗糙的操作来实现这一点,但如果您有多个Phaser实例在运行,这将不起作用

如果有人知道正确的工作流程应该是什么,我很想知道--Phaser.CanvasPool是Phaser与PIXI的联系点之一,所有这些似乎都没有很好的记录

编辑:找到内存泄漏的源。它是Phaser.Utils.Debug.boot(),每次调用它时都会向池中添加一个新画布,默认情况下,每次创建和启动Phaser实例时都会添加新画布

启用enableDebug(默认设置)时,该问题仅影响WebGL渲染画布

为完整起见,下面是上述代码的编辑版本,它禁用调试,因此不会出现内存泄漏:

<!doctype html>
<html>
<head>
<meta charset="UTF-8"/>
<title>test</title>
<script src="http://cdnjs.cloudflare.com/ajax/libs/phaser-ce/2.8.1/phaser.js"></script>
</head>
<body>
<button id="button">Click</button>
<div id="canvas"></div>
<script>
window.onload = function() {
    var d, n, game;

    d = document.getElementById('button');
    n = document.getElementById('canvas');

    function preload() {
    }
    function create() {
    }
    function update() {


    }
    function handler() {
            if(game) {
                    game.destroy();
                    game = null;
            } else {
                    game = new Phaser.Game({
                            width:          800,
                            height:         600,
                            renderer:       Phaser.AUTO,
                            parent:         n,
                            enableDebug:    false,
                            state:          {
                                    preload:        preload,
                                    create:         create,
                                    update:         update
                            },
                    });
            }
    }
    d.onclick = handler;
};
</script>
</body>
</html>

测试
点击
window.onload=函数(){
变量d,n,对策;
d=document.getElementById('button');
n=document.getElementById('canvas');
函数预加载(){
}
函数create(){
}
函数更新(){
}
函数处理程序(){
如果(游戏){
游戏。破坏();
game=null;
}否则{
游戏=新的移相器。游戏({
宽度:800,
身高:600,
渲染器:Phaser.AUTO,
家长:n,
enableDebug:false,
声明:{
预加载:预加载,
创建:创建,
更新:更新
},
});
}
}
d、 onclick=handler;
};

我不是JS专家,但有没有可能只是“还没有”被GC清理掉?没有——内存永远不会被垃圾收集,不管是等待还是强制垃圾收集(例如使用Chrome的开发工具)。