BabylonNative icon indicating copy to clipboard operation
BabylonNative copied to clipboard

Demo projects take too much memory

Open ZhuoYitao opened this issue 3 years ago • 9 comments

Either the Android demo project or the iOS demo project takes more than 100MB memory. Considering they simply render a cube, the memory cost is too large. Is there any suggestion to reduce the memory usage?

P.S. I've changed some configs in 'Dependencies/bgfx.cmake/bgfx/src/config.h', such as the 'BGFX_CONFIG_MAX_DRAW_CALLS' definition, but the total memory keeps unchanged.

ZhuoYitao avatar May 23 '22 09:05 ZhuoYitao

Hi @bghgary, do you have any idea about this issue? Please let me know if I need to add more information.

ZhuoYitao avatar May 24 '22 03:05 ZhuoYitao

Sounds related to #726 (or at least that issue probably has relevant context).

ryantrem avatar May 24 '22 04:05 ryantrem

https://github.com/bkaradzic/bgfx/issues/1715

Hi @ryantrem, bgfx does reserve a large amount of memory. Changing configs of bgfx can reduce the allocated heap. For example, modify the value of 'BGFX_CONFIG_MAX_DRAW_CALLS' in 'Dependencies/bgfx.cmake/bgfx/src/config.h' to '64' can reduce more than 60MB of heap allocation. Confusingly, the total memory usage is not changed.

ZhuoYitao avatar May 24 '22 08:05 ZhuoYitao

@ZhuoYitao Have you tried capturing a memory profile to see where the allocation is? The memory usage could be on the native side or maybe it's on the JS side.

bghgary avatar May 24 '22 20:05 bghgary

@bghgary I will have a look at it.

ZhuoYitao avatar May 25 '22 05:05 ZhuoYitao

Hi @bghgary,I notice that the LoadScript() method in the ScriptLoader class could cause a huge memory usage. When I comment out all lines in the "app:///Scripts/babylon.max.js" file (which means no meaningful JS code will be run), running loader.LoadScript("app:///Scripts/babylon.max.js") still takes about 88MB of memory. Could you have a try at optimizing the loader?

Here is more information about loading the commented "babylon.max.js" file:

  1. Running "m_responseString = std::string{static_cast<const char*>(data.bytes), data.length};" in "Dependencies/UrlLib/Source/Apple/UrlRequest.mm" takes about 25MB of memory.
  2. Running "NAPI_THROW_IF_FAILED(env, napi_run_script(env, Napi::String::New(env, source), sourceUrl, &result))" in "Dependencies/napi/napi-direct/source/env.cc" takes about 50MB of memory.

ZhuoYitao avatar May 30 '22 03:05 ZhuoYitao

Running "m_responseString = std::string{static_cast<const char*>(data.bytes), data.length};" in "Dependencies/UrlLib/Source/Apple/UrlRequest.mm" takes about 25MB of memory.

This one is interesting. Does this string not get released later? If not, then this is a bug.

Running "NAPI_THROW_IF_FAILED(env, napi_run_script(env, Napi::String::New(env, source), sourceUrl, &result))" in "Dependencies/napi/napi-direct/source/env.cc" takes about 50MB of memory.

This is normal, in the sense that babylon.max.js is a big file with everything in it. It is also the max file (i.e., it is not minified). This is what the Playground app does because it is expected that it can use any Babylon.js API similar to the web Babylon.js playground. Using the max file is just so that it's easier to debug the JS code. One quick thing you can do is change this to load the minified babylon.js instead which should reduce the memory immediately.

Typically speaking, for real apps, the build should be using a bundler (e.g., webpack) with tree-shaking and minification to reduce the size of the loaded JS file. That should reduce the amount of memory being consumed from this call. It will also reduce the memory being used from the former issue, but that string should be transient and not stick around.

bghgary avatar May 31 '22 21:05 bghgary

@bghgary Indeed, using the minified babylon.js can reduce the memory. But the reduced memory is still too large to embed Babylon Native into a mobile app. I guess there is memory leak(s) in the LoadScript() method.

ZhuoYitao avatar Jun 01 '22 02:06 ZhuoYitao

But the reduced memory is still too large to embed Babylon Native into a mobile app.

Yes, I just mean you can test it to see how much it affects memory. You should use a JS bundler with tree-shaking and minification if you want to deploy to production, just like you would for Babylon.js in a browser.

I guess there is memory leak(s) in the LoadScript() method.

I can't rule this out. If you can confirm this, that'll be helpful.

bghgary avatar Jun 01 '22 20:06 bghgary

@ZhuoYitao Are you still seeing issues with this? If so, please reopen.

bghgary avatar Oct 13 '22 18:10 bghgary