Version
- Phaser Version: 4.0.0
- Operating system: MacOS Monterey v12.7.6
- Browser: all browsers
Description
When Phaser.Game is destroyed and a new instance is created on the same page, retained heap memory for TilemapLayerWebGLRenderer nearly doubles with each cycle.
class MainScene extends Phaser.Scene {
constructor() {
super({ key: "MainScene" });
}
preload() {
this.load.setBaseURL('https://cdn.phaserfiles.com/v385');
this.load.image('walls_1x2', 'assets/tilemaps/tiles/walls_1x2.png');
}
create() {
const map = this.make.tilemap({ width: 200, height: 200, tileWidth: 32, tileHeight: 32 });
const tiles = map.addTilesetImage('walls_1x2', null, 32, 64);
const layer = map.createBlankLayer('layer1', tiles);
layer.randomize(0, 0, map.width, map.height, [ 0, 1, 2, 3, 4, 5, 6, 7 ]);
}
}
let game = null;
const getGame = () => game;
function createGame() {
game = new Phaser.Game({
type: Phaser.AUTO,
width: 800,
height: 800,
backgroundColor: '#111111',
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_BOTH
},
scene: [ MainScene ]
});
}
function destroyGame(gameInstance) {
gameInstance.events.once('destroy', () => {
game = null;
});
gameInstance.destroy(true);
}
setInterval(() => {
if (!getGame()) {
createGame();
} else {
destroyGame(getGame());
}
}, 6000);
Additional Information
Possible issue at src/tilemaps/TilemapLayerWebGLRenderer.js :
Module-level singleton retains glTexture reference across Phaser.Game instances. Declares two module-level objects that persist for the entire lifetime of the JavaScript module (i.e. they are never GC'd).
During every render call, the live glTexture from the active Tileset is written into texturerData:
texturerData.frame.source.glTexture = tileset.glTexture;
When WebGLRenderer.destroy() is called (via game.destroy()), it correctly iterates glTextureWrappers and calls .destroy() on each. However, texturerData.frame.source.glTexture is never nulled out.
Version
Description
When Phaser.Game is destroyed and a new instance is created on the same page, retained heap memory for TilemapLayerWebGLRenderer nearly doubles with each cycle.
Example Test Code (in phaser sandbox)
Additional Information
Possible issue at
src/tilemaps/TilemapLayerWebGLRenderer.js:Module-level singleton retains glTexture reference across Phaser.Game instances. Declares two module-level objects that persist for the entire lifetime of the JavaScript module (i.e. they are never GC'd).
During every render call, the live glTexture from the active Tileset is written into texturerData:
texturerData.frame.source.glTexture = tileset.glTexture;When WebGLRenderer.destroy() is called (via game.destroy()), it correctly iterates glTextureWrappers and calls .destroy() on each. However, texturerData.frame.source.glTexture is never nulled out.