How to restart a level (dispose of previous one) without memory leak? - SEQUEL

Hello!

This is the sequel of this thread: How to restart a level (dispose of previous one) without memory leak? - Questions & Answers - HTML5 Game Devs Forum

To summarise the previous thread: I made a piece of code that runs a loop where it:

  • generates a maze,
  • displays it for few seconds,
  • disposes of the scene and the UI (advance texture)

I’ve got some evidence that there is a memory leak because, after some iterations the framerate drops and the CPU load increased.

To make a PG example of my problem is a bit complicated because I basically need a lot of my functions/objects/textures/assets to run the example.

Hence, instead I made a branch on Bitbucket that you can clone, but I can not share it publicly, so you would need to PM me if you’re interested in having a look (yeah, I am decreasing all my chances to be helped! sorry :confused: ).

New episode

I realised that last time, I had the inspector opened! hence that may be why the CPU was bloated!

I re-run my test without the inspector (and some optimisation using mergeMeshes() / SPS), that works much better in term of CPU, but we can still see a leak after few scene reloads.

Here the first few scene reloads. You can see that the CPU is at 100% when I load the maze, then the processor relaxes during the game (yellow curve in the top graph), the FPS is at 0 during the loading time (cause 1 static image) and ~60 during the game (the green curve in the top graph).

opera_2018-12-13_14-53-06.thumb.png.8056e0c6ec2a62cdc859cc692aa51de5.png

1 Like

(I had to split cause new user aren’t allow to post more than 1 image!)

After a few scene reloads, I recorded again. You can see that the CPU does not relaxes as well as before during the game (yellow curve in the top graph), the FPS drop at ~50 during the game (the green curve in the top graph).

opera_2018-12-13_14-55-11.thumb.png.abc34cec00a0897c95708055cecea0dd.png

Any thoughts?

I would like to ping @Deltakosh on that one, cause he was in holidays at the time I started the thread ! :slight_smile:

Thanks for your help !

Hey thanks for pinging me:)
We will need a repro to help because disposing the scene should be enough to. Some things are not disposed because they are hold by the engine like shaders or shared textures.

Perhaps you can do a profile of who is using the CPU? Seems a good starter. Compare at beginning and after a few cycles. Who is the top consumer? Time spent on what etc…

Nice post by the way. and interesting.:blush:

Do you have a Bitbucket account? I can add you to the project and there will be a branch with the code ready to run. Sorry for the inconvenience, but that’s a contracted work :confused: so I can’t really share it publicly.

Can you narrow it down in the PG? It is by far the better way to get something fixed :wink:

I don’t know how to load my assets in the PG … :confused:

https://doc.babylonjs.com/resources/external_pg_assets

Ok, I will have to see how I can serve the files without breaching the confidentiality on the project :confused:

It will take me some time to make the repro in PG as I need to progress on my contracted work in priority :slight_smile: but hopefully we will get there.

AS soon as you can repro I promise to be quick :smiley:

Here’s a post from the old forum that worked at the time:

Starting form fresh, with a simple (and clean ;)|20x20 ) project, I could make the dom destruction/reconstruction work fine with Babylon engine. But after a few cycles of creating a canvas DOM node, creating a babylon engine, building up a dummy scene, disposing the engine, destroying the canvas node, I ended up with a strange chrome warning saying there were too many webgl contextes. This seems to be a known issue inherent to js garbage collection. For me that was the final proof saying that this is definitely the wrong pattern here, as Temechon said.

And reinitializing the scene is simple by doing so:

engine.stopRenderLoop();engine.clear(BABYLON.Color3.Black(),false,false);window.removeEventListener(‘resize’);if (engine.scenes.length!==0) { //if more than 1 scene, while(engine.scenes.length>0) { engine.scenes[0].dispose();}

I couldn’t observe any memory leak doing this dozens of time, it seems pretty reliable.

I will keep developing with that method, which is simple and clean.

If you wish to view the entire topic:

Galen

1 Like