Frequently Dispose AssetContainer Causes Memory Leak

Hi Team,

I found this issue when I load glb file by using LoadAssetContainerAsync.

My repro method has three steps:

  1. set a timer to execute loadAssetContainerAsync every 100ms
  2. call addAllToScene() in its callback function.
  3. dispose() after addAllToScene()

The snapshot shows that the numbers of arraybuffer, objects and array increases gradually. It seems to have GC process during the process, but the overall numbers keeps growing.

20220320164203

I also using a webkit profiling tool to check the trend on my iphone12, it looks like the following graph.
Both physical memory and memory go up stably like going upstairs and the avaliable memory drops.

I try to repro this in this file.
body_man.zip (58.5 KB)

Hoping you guys can take a look and see what happens.
Thank you in advance for your concern.

You are not waiting for one load being over to start the new one so if they take more than 100ms You will have a lot in parallel, @bghgary tried this successfully not long ago IIRC ?

Hi sebavan,

Thank you for your reply. Sure it may take longer than 100ms since it is a async function. I tried 1000ms which loading process can be finished and it got slower increase.

I found this one may relate to this issue:

Other observations:

  1. If I use scene.onDisposeObservable.clear() after disposing assetContainer, the empty assetcontainer class will be cleaned.
  2. using chained Promise and returns Promise(assetcontainer) causes faster memory increase than just return the assetcontainer itself.

Could you please provide a repro in the playground ? @Deltakosh is kiiling leaks at the moment but it is really hard without a repro.

Sure I will put the code in zip file on the playground. While for the repro in zip file (above one) I load the glb file locally, but on playground I may use a remote one, which may introduce the request time and network problem. So I wonder if there is some approach load the glb in playground locally?

You can have a look here Using External Assets In the Playground | Babylon.js Documentation

And instead of a zip file, you can simply save the playground and share the URL :slight_smile:

Hello @RavenLee just checking in if you are able to provide a playground repro for us to take a further look at this

Hi carolhmj,

Thank you for your cencern for this issue. I am struggling with providing a proper online repro on this issue. While fortunnately I found some clues, if you have a look at the zip file and run it by a local server. if I QueryObject(AssetContainer) there are some AssetContainer empty left.


If I track the onDisposeObservable, there are many of them in the stack. when disposing the assetContainer, removing onDisposeObservable helps, but I cannot figure them all.

I’m taking a look at the zip, and after adding the Inspector to look at the scene nodes, these skeletons immediately caught my attention:

And looking at the code, I noticed there’s both a call to addAllToScene AND instantiateModelsToScene, the second of which DOES duplicate the skeletons, as per documentation: AssetContainer | Babylon.js Documentation (babylonjs.com). After properly disposing of these skeletons by using the returned skeletons property returned by instantiateModelsToScene, the memory usage doesn’t grow anymore.

1 Like