销毁 Phaser.Game 实例的正确方法是什么?
What's the proper way to destroy instance of Phaser.Game?
在创建然后销毁 Phaser.Game 实例的微不足道的情况下,似乎存在内存泄漏。下面是一个完整的工作示例:单击按钮创建一个实例,再次单击将其销毁。重复单击该按钮会导致内存使用量无限制地增长。关于我应该做的移相器生命周期,我是否遗漏了什么?
我将其作为代码片段而不是 jsfiddle 发布,因为您需要查看内存分析器或类似的东西才能看到问题,因此 jsfiddle 只会使问题复杂化。
<!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>
回答(至少部分)我自己的问题,问题在 Phaser.CanvasPool。每当创建新的 Phaser 实例时,都会创建一个新的 canvas 并将其添加到池中。销毁实例不会从池中删除 canvas 或将其标记为可重复使用。
你可以通过在调用 game.destroy() 之后做一些粗略的事情来解决这个问题,比如设置 Phaser.CanvasPool.pool = [],但是如果你有多个,那将不起作用移相器实例进行中。
如果有人知道正确的工作流程应该是什么,我很想知道---Phaser.CanvasPool 是 Phaser 与 PIXI 的联系点之一,所有这些似乎都没有很好的记录。
编辑:找到内存泄漏的根源。它是 Phaser.Utils.Debug.boot(),它会在每次调用时向池中添加一个新的 canvas,默认情况下是每次创建和启动移相器实例时。
当 enableDebug 启用(默认设置)时,该问题仅影响 WebGL 渲染的 canvases。
为了完整起见,这里是上面代码的编辑版本,它禁用调试,因此不会出现内存泄漏:
<!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>
在创建然后销毁 Phaser.Game 实例的微不足道的情况下,似乎存在内存泄漏。下面是一个完整的工作示例:单击按钮创建一个实例,再次单击将其销毁。重复单击该按钮会导致内存使用量无限制地增长。关于我应该做的移相器生命周期,我是否遗漏了什么?
我将其作为代码片段而不是 jsfiddle 发布,因为您需要查看内存分析器或类似的东西才能看到问题,因此 jsfiddle 只会使问题复杂化。
<!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>
回答(至少部分)我自己的问题,问题在 Phaser.CanvasPool。每当创建新的 Phaser 实例时,都会创建一个新的 canvas 并将其添加到池中。销毁实例不会从池中删除 canvas 或将其标记为可重复使用。
你可以通过在调用 game.destroy() 之后做一些粗略的事情来解决这个问题,比如设置 Phaser.CanvasPool.pool = [],但是如果你有多个,那将不起作用移相器实例进行中。
如果有人知道正确的工作流程应该是什么,我很想知道---Phaser.CanvasPool 是 Phaser 与 PIXI 的联系点之一,所有这些似乎都没有很好的记录。
编辑:找到内存泄漏的根源。它是 Phaser.Utils.Debug.boot(),它会在每次调用时向池中添加一个新的 canvas,默认情况下是每次创建和启动移相器实例时。
当 enableDebug 启用(默认设置)时,该问题仅影响 WebGL 渲染的 canvases。
为了完整起见,这里是上面代码的编辑版本,它禁用调试,因此不会出现内存泄漏:
<!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>