Search Unity

Webgl never releasing memory

Discussion in 'WebGL' started by dcorne, Mar 7, 2018.

  1. dcorne

    dcorne

    Joined:
    Jul 15, 2015
    Posts:
    2
    Hi! I'm not able to release memory in webgl.
    The memory allocated when I download an assetbundle is never released. I've tryed everything I've found; destroy objects, unload assetbundles, disposing the request, unload unused assets, cleaning cache... Nothing works. Even if I change scene, memory is still allocated.
    If I use the profiler (both in editor and autoconnected), I can see how memory increments and decreases when I unload things, but then, in the browser it's as if the garbage collector, is never, never working.
    I'm in Unity 5.5.1f and it's happening, both in Chrome and in Firefox (last versions).
    Any help, please?
    I'm quite desperate...
     
  2. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    351
    Garbage collection only happens inbetween frames on webGL.
    On webGL memory management is a bit different than a build for standalone.
    You should read up the blog(s) and manual about webGL memory.

    Like this one:
    https://blogs.unity3d.com/2016/09/20/understanding-memory-in-unity-webgl/

    Do mind that this blog post is old and contains old API. Use UnityWebRequest for downloading bundles and not WWW.
    The WWW class will be deprecated/obsolete.
    Also a lot has changed in the meanwhile between 5.5.1 - 2017.3.1.
    Try to keep Unity up to date as much as possible especially for webGL it is good to keep up with the newer versions due to fixes and optimizations

    My advice would be:
    Try to keep the bundles as small as possible or even split them up in multiple bundles so that the browser doesn’t have to allocate a lot of memory as download buffer for the bundle.
     
    Last edited: Mar 13, 2018
  3. andrzej_cadp

    andrzej_cadp

    Joined:
    Jan 27, 2017
    Posts:
    18
    That's probably the best advice you could get. Gap between these two versions is huge both in performance and stability. You should do everything to keep Unity version up to date. WebGL is rapidly improving and every major unity update brings something new.
     
  4. dcorne

    dcorne

    Joined:
    Jul 15, 2015
    Posts:
    2
    When we started, it was easier to keep that Unity version than change it. Now I'm not so sure ... In any case, thank you very much @MaskedMouse and @andrzej_cadp for the advices. I'll keep them in mind!
     
  5. Marco-Trivellato

    Marco-Trivellato

    Unity Technologies

    Joined:
    Jul 9, 2013
    Posts:
    1,653
    The blog post is a bit old but most of it still apply to recent releases. One thing I should mention is that GC.Collect() works now, the only difference compared to other platforms, is that the garbage collection happens with one frame of delay.
     
  6. NSdesignGames

    NSdesignGames

    Joined:
    Dec 29, 2010
    Posts:
    494
    GC.Collect() may work in theory but on practice it doesn't, not even on scene load. (Tested in Unity 2017 and 2018 b7,8,9)
    I have reported a bug some time ago (Case 1004043)
     
  7. Marco-Trivellato

    Marco-Trivellato

    Unity Technologies

    Joined:
    Jul 9, 2013
    Posts:
    1,653
    thanks for that bug report. I have started looking at it.

    I think GC.Collect per se actually works. IIRC your repro:
    1. allocates a big chunk of memory in one go
    2. deallocate
    3. garbage collect
    4. tries to re-allocate another block of the same size.
    The problem is that this relies on the fact that no other block is allocated between 3 and 4. If another allocation sneaks in, then the free block becomes smaller/fragmented. From what I have seen, we do have some internal engine allocations that happen every frame. Although I think most of them are temporary, they might fragment memory.
    I really think this is something we should fix, however, based on this consideration it would be interesting to:
    1. allocates a big chunk of memory in one go
    2. deallocate
    3. garbage collect (either swap scene or call GC.Collect and wait at least one frame)
    4. allocate a lot of smaller blocks that altogether approximately amount to the size of the block in #1
    If this does not work, then we have a GC problem.

    I hope this makes sense.
     
    StaffanEk likes this.
  8. NSdesignGames

    NSdesignGames

    Joined:
    Dec 29, 2010
    Posts:
    494
    Ok, I have attached a slightly changed TestScript from repro project.
    In first scene I allocate 150mb and even call GC.Collect() after.
    Then in second scene I call "for" loop allocating 10mb per iteration.
    The result is: 150mb allocated in first scene, then in second scene it crashes after iteration 5, so it wasn't even able to allocate 70mb.
    Memory size is default 256mb.

    Conclusion: Once the memory is allocated in WebGL it becomes unusable for future allocations.
     

    Attached Files:

  9. Marco-Trivellato

    Marco-Trivellato

    Unity Technologies

    Joined:
    Jul 9, 2013
    Posts:
    1,653
    Thanks, I'll take a look at it on my side.
     
  10. savely00

    savely00

    Joined:
    Feb 27, 2014
    Posts:
    29
    What is the correct way to Unload\Release Unity in WebGL build?
    Application.Quit() dos not work.
    We have a SPA with Unity in a tab. When we are switching tabs,Unity instance does not get destroyed and consumes a lot of memory. Any suggestion?
     
  11. StaffanEk

    StaffanEk

    Joined:
    Jul 13, 2012
    Posts:
    380
    Would it be possible to manually track memory usage for specific objects, kinda like using C? This way we could keep track of objects that would be prone to GC issues. Could calling GC manually help in certain situations?
     
  12. bigbrainz

    bigbrainz

    Joined:
    Jul 21, 2015
    Posts:
    84
    Marco, any insight on this? It seems we're struggling with the same issue.
     
  13. reigota

    reigota

    Joined:
    Mar 23, 2010
    Posts:
    62
    savely00, OneManArmy3D and StaffanEk like this.
  14. savely00

    savely00

    Joined:
    Feb 27, 2014
    Posts:
    29
    @Marco-Trivellato , is any work done recently in this area?
    It seems that WebGL is falling behind all other new 'cool features'.
     
  15. Marco-Trivellato

    Marco-Trivellato

    Unity Technologies

    Joined:
    Jul 9, 2013
    Posts:
    1,653
    We have a mechanism for this in 2019.1, check this post.
     
  16. Marco-Trivellato

    Marco-Trivellato

    Unity Technologies

    Joined:
    Jul 9, 2013
    Posts:
    1,653
    I believe there is a fragmentation problem so large allocations might fail because of that. We still need to investigate.
     
  17. Marco-Trivellato

    Marco-Trivellato

    Unity Technologies

    Joined:
    Jul 9, 2013
    Posts:
    1,653
    which cool features?
     
  18. Marco-Trivellato

    Marco-Trivellato

    Unity Technologies

    Joined:
    Jul 9, 2013
    Posts:
    1,653
    I think the new memory profiler might help with this but personally I haven't used it yet.
     
    savely00 likes this.
  19. savely00

    savely00

    Joined:
    Feb 27, 2014
    Posts:
    29
    I did not hear any mentioning of WebGL on Unite LA 2018 nor Berlin 2018.
    It would be nice to have some new intermediate or advanced tutorials on Unity 2018/2019 WebGL.
     
  20. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    143
    I have this problem again since 2018.3
    Code (CSharp):
    1. Resources.UnloadUnusedAssets();
    2. GC.Collect();
    This works in a standalone bulids.
    In WebGL the memory size only goes in one direction. Up and Up and Up.... (And it already start with a very high value...125-128MB. It was ~15MB in 2018.2)

    any idea why? I did not have this problem in 2018.2
     
  21. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    351
    If you compare the same build one built with 2018.2 and the other with 2018.3 and there is a difference in size. Then it might be a bug. You should do a bugreport then.

    Here at our work we stopped using Unity WebGL and started using ThreeJS as it is a lot faster starting up, lightweight on memory (due to GLTF / GLB) and iteration is a lot quicker as it requires less time compiling a build. A big downside to that is we miss a lot of the API that Unity offers out of the box of course.
     
  22. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    143
    I tried both versions again and i was wrong... 15MB memory was my standalone app. WebGL had ~125 MB too.
    And GC.Collect() also had no effect on 2018.2.
    It seems the only way to clean up in WebGL is to reload everything.
    my bad.
     
  23. AlexHell

    AlexHell

    Joined:
    Oct 2, 2014
    Posts:
    160
    If GC.Collection does nothing then your assets is used :)
    For example you have many meshes + textures + may be huge C# object instance count, which is coupled to each other.
     
  24. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    143
    It does something in the standalone app, but nothing in WebGL.
    My app allow to upload own textures. If i delete all objects to start a new project, i call GC.Collect.

    Memory before GC.Collect: ~50Mb, after GC.Collect ~15Mb.
    Same in WebGL... before 250Mb, after 250Mb.
     
  25. AlexHell

    AlexHell

    Joined:
    Oct 2, 2014
    Posts:
    160
    Ok, sorry, then it's a bug
     
  26. MFKJ

    MFKJ

    Joined:
    May 13, 2015
    Posts:
    189
    I unloaded the bundle, destoryed the gameobject that load with bundle, even run System.GC.Collect but the problem is that my memory is not releasing. As the thread suggested this (https://forum.unity.com/threads/quit-and-memory-cleanup.571210/) New Quit method in Unity 2019 can release the memory but unity 2019 is on initial stage beta version. What should i do? Here is my problem details.
     
  27. MFKJ

    MFKJ

    Joined:
    May 13, 2015
    Posts:
    189
    did you fixed the problem? I am looking for the same solution? how did you control it?
     
  28. Aiursrage2k

    Aiursrage2k

    Joined:
    Nov 1, 2009
    Posts:
    4,790
    Okay the good news is that 2019.1+ has an incremental garbage collection function but its not enabled for webGL yet... but i did test it it in the editor and it does actually delete the memory which would solve our ram problem (or at least part of it).

    https://forum.unity.com/threads/incremental-gc-feedback-thread.588664/page-2
     
    Last edited: Mar 13, 2019
  29. MFKJ

    MFKJ

    Joined:
    May 13, 2015
    Posts:
    189
    In unity 2019 there is quit method that can release the memory but the problem is unity 2019 is in beta format correctly. Moreover, if GC works when you load a new scene then it will defineatly release the memory?
     
  30. kognito1

    kognito1

    Joined:
    Apr 7, 2015
    Posts:
    293
    I know probably not helpful for everyone, but I can confirm memory is released on level load change with webgl.
     
  31. MFKJ

    MFKJ

    Joined:
    May 13, 2015
    Posts:
    189
    additivie scene loading will make the same effect? will it release the memory ? Thanks for your response can you share the details
     
  32. kognito1

    kognito1

    Joined:
    Apr 7, 2015
    Posts:
    293
    Here's what we do: "current scene" -> [non-additive scene load] -> "almost a completely empty scene" -> [additive scene load] -> "next scene"

    If you run the memory profiler, you'll see the memory on the heap drop when loading the empty scene level and then gradually increase as the next level is additively loaded (and then a final smaller drop off after you unload unused asset bundles). You can essentially do this forever. Some fragmentation will occur after loading and unloading several levels but that hasn't really impacted us in practice (more of mobile thing).
     
  33. MFKJ

    MFKJ

    Joined:
    May 13, 2015
    Posts:
    189
    Well, I tested:

    one main scene loading an additive scene, before loading the additive scene my webgl memory usage

    WebGL Memory - Total: 784MB, Used: 128MB,

    after loading additive scene

    WebGL Memory - Total: 784MB, Used: 128MB, Free: 561MB

    after unloading additive scene, the memory remain the same, there is no release of the memory.
    I am using WebGLMemoryStats script by kongregate, I don't know where is the problem. Either my memory logging is not same or additive scene don't make any effect on memory release.
     
  34. kognito1

    kognito1

    Joined:
    Apr 7, 2015
    Posts:
    293
    That might be measuring the underlining wasm heap. I'm pretty sure once you've grown the heap, Unity never tries to reclaim any of that space. However it will reuse any freed memory within that space before it tries to grow the wasm heap again (you can view this in the Unity profiler). I'd try to think of that number as your new "maximum".
     
  35. MFKJ

    MFKJ

    Joined:
    May 13, 2015
    Posts:
    189
    I found that WebGL Memory Stats :
    It is important to note that the data Unity/Emscripten provides here appears to be a high watermark for memory usage. That is, when objects are cleaned up, the used/free memory does not change. However, it is still crucial as a tool for measuring and tuning how much memory to allocate for your Unity heap. You should use this tool to keep track of the highest amount of memory used, and then add a safety net on top of that while rounding up to the next highest 16MB.

    Maybe the memory is releasing when loading the scene?
    Even asset bundle unload/destroy also releasing the memory?

    I have get stuck in unity webgl, I don't know what combination should i use for webgl and asset bundle.
     
  36. kognito1

    kognito1

    Joined:
    Apr 7, 2015
    Posts:
    293
    Yeah it probably is being freed, just make a development build that auto-connects to the Unity profiler and see for yourself!
     
  37. Aiursrage2k

    Aiursrage2k

    Joined:
    Nov 1, 2009
    Posts:
    4,790
    Any updates on GC for webgl, is it possible to do it without having to reload the scene? Okay i can load a few files, but eventually it runs out of memory because we cant do any garbage collection.
     
    Last edited: Mar 21, 2019
  38. MFKJ

    MFKJ

    Joined:
    May 13, 2015
    Posts:
    189
    Do you able to solve the issue?
     
  39. MFKJ

    MFKJ

    Joined:
    May 13, 2015
    Posts:
    189
    I can't confirm but @kognito1 stated that memory do release when you load new scene. If you don't want to load anything using new scene then you can try it with empty additive scene. Please let us know that it works or not.
     
  40. Aiursrage2k

    Aiursrage2k

    Joined:
    Nov 1, 2009
    Posts:
    4,790
    Okay that might be a good crazy workaround that I never would even thought about, I will let you know if that works later today. If that works we are back in business
     
    MFKJ likes this.
  41. MFKJ

    MFKJ

    Joined:
    May 13, 2015
    Posts:
    189
    Well I have get stuck in a very weird situation, posted on different unity threads but unable to find answer.

    My problem is that whenever I reload the unity webgl page on chrome, it double the memory. I can see it in chrome task manager that memory footprint are increasing with each page reload. I don't know why it is happening. Has anyone experience it or can any one help? It seriously hitting the feasibility of my project where i have done so many things. Please if any has insight about the problem,help.

    Remember it some time work properly but mostly increment the memory on each page reload(it work well when i close the tab but when i reload same page again and again it show memory leak problem).
     
  42. Aiursrage2k

    Aiursrage2k

    Joined:
    Nov 1, 2009
    Posts:
    4,790
    The only thing I can think is that you are saving stuff in the indexdb and when its reloading the scene its keeping that content in memory.
     
  43. MFKJ

    MFKJ

    Joined:
    May 13, 2015
    Posts:
    189
    Thanks for valueable response

    The build has enable cache check set to true , while i am loading asset bundle through xmlhttprequest plugin.
    Maybe this is the problem?
     
  44. MFKJ

    MFKJ

    Joined:
    May 13, 2015
    Posts:
    189
    But even without loading the asset bundle i am getting this error.
     
  45. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    143
    nope

    but i solved my memory problem almost by NOT instantiate from resources.
    i load all resources in a list on start, and instantiate from the list.
    the app start now with ~450MB. but it's stable.