kittykatattack / hexi

Make games the fun way!
MIT License
551 stars 83 forks source link

How would I prevent this from leaking memory? #41

Closed SuperCuber closed 3 years ago

SuperCuber commented 6 years ago
let g = hexi(1000, 1000, setup);
g.border = "2px red dashed";
g.backgroundColor = 0x000000;
g.scaleToWindow();
g.start();

var scene, tiles;

function setup() {
    g.state = play;
    scene = g.group();

    tiles = [];
    for(i = 0; i < 20; i++) {
        var row = [];
        for(j = 0; j < 20; j++) {
            var color = (i + j) % 2 == 0 ? "#ffffff" : "#000000";
            var tile = g.rectangle(50, 50, color, null, 0, 50*i, 50*j);
            row.push(tile);
            scene.add(tile);
        }
        tiles.push(row);
    }

    index = 0;
}

var index;

function setTileColor(x, y, color) {
    scene.removeChild(tiles[index][index]);
    tiles[index][index] = g.rectangle(50, 50, color, "#000000", 0, 50*index, 50*index);
}

function play(){
    for(i = 0; i < 100; i++) setTileColor(0, 0, "#ff0000");
}

The play function is obviously just for testing, but if you run this for a couple of seconds you can see firefox's memory usage rising dramatically. So my question is how do I prevent this code from leaking memory?

AnthyG commented 6 years ago

When I'm not mistaken, removeChild doesn't actually delete the object, but it just removes it from the parent, it has been called from. So basically, you're creating 100 new tiles every time, you start play again. Rather just set the current object's colour.

SuperCuber commented 6 years ago

How would I set the color? Also how would I delete the object if I wanted to?

kittykatattack commented 6 years ago

http://www.html5gamedevs.com/topic/30539-correct-way-to-remove-sprites-container/

and

http://www.html5gamedevs.com/topic/19815-correct-way-of-deleting-a-display-object/

kittykatattack commented 6 years ago

@supercuber: Just out curiosity, if there a different memory usage result if you run that for inside a requestAnimationFrame event loop? (instead of usingg.state = play)

SuperCuber commented 6 years ago

@kittykatattack the links are to questions about that topic, but doesn't look like there is an answer... I am not really sure what do you mean by requestAnimationFrame

kittykatattack commented 6 years ago

@SuperCuber: Ivan's answer explains it:

"DisplayObjects are taken by javascript GC. Textures that weren't used for 2-3 minutes or so, will be collected by pixi GC which is turned on by default. You can turn it off if it gives you lags. But if you dont destroy BaseTexture's , images will still live in "PIXI.utils.TextureCache", but they will be in png form (browser optimizes that), which is small compared to fully loaded texture"

Which means Pixi's garbage collector should clear memory intermittently, but it won't clear the BaseTexture. If you need to clear the BaseTexture, use the destroy method: http://pixijs.download/dev/docs/PIXI.BaseTexture.html#destroy

Regarding requestAnimationFrame, instead of using Hexi's built-in play function, create your own game loop and use it to update the game:

https://www.sitepoint.com/quick-tip-game-loop-in-javascript/

SuperCuber commented 6 years ago

So you are saying that 2 possible solutions to my problem is:

1) If I don't do a lot of changes quickly it will not be a problem since old stuff will get cleared after some time 2) Call manually requestAnimationFrame(?)

kittykatattack commented 6 years ago

@SuperCuber

  1. Yes, it seems that way from Pixi's documentation (Hexi is really just a collection of convenience functions for working with Pixi.)

  2. My suggestion for trying your code with requestAnimationFrame is really just for you to test whether the problem goes away if you don't use Hexi's automated game loop using g.state = play; and instead use your own game loop. If there's a significant memory usage difference then there's probably a bug in Hexi's game loop that we should investigate.

SuperCuber commented 6 years ago

I don't really understand how to convert my code D:

kittykatattack commented 6 years ago

@SuperCuber: No problem - my guess is that the memory usage is normal (?) so there's probably no need to do any testing. If anyone else would like to comment on this, please do!