Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Tackling memory

Discussion in 'Web' started by diekeure, Nov 25, 2015.

  1. diekeure

    diekeure

    Joined:
    Jan 25, 2013
    Posts:
    221
    Hi,

    We're making good progress on our webgl port of our game, and we had a lot of help here on the forum to get there, for which I'm very greatfull.

    One of the remaining issues that I need to tackle is memory consumption by the browser.

    I've read these two manual pages:
    to get things most optimal.

    Our details:
    • Code stripping is on
    • No data caching
    • 512MB unity heap
    • Exceptions is set to None
    • We build via script with this command:
      Code (csharp):
      1. BuildPipeline.BuildPlayer(levels, "Build/kweetet-webgl", BuildTarget.WebGL, BuildOptions.None);
    • No WWW.LoadFromCacheOrDownload calls
    • Assetbundles are unloaded as soon as all the required assets are loaded/instantiated

    When our game's first level is fully loaded, I have these numbers for firefox:



    With a development build I see in the webconsole reported that there is 80mb memory in use, which seems plausible if compared with the memory usage reported in the profiler.

    So the unity heap takes 512mb, we use not that much so I can make that smaller. But I'd like to tackle the remaining 1234mb that Firefox uses. If I understand correctly, this is all about the browser parsing and running the javascript code, so the less code we have, the less memory there will be used.

    Things I tried/noticed:
    • I excluded a 3rd party dll we use and had a difference of +/- 20mb (not much, but something).
    • I have this in my build script:
      Code (csharp):
      1. PlayerSettings.SetPropertyString("emscriptenArgs", "-s DEMANGLE_SUPPORT=1", BuildTargetGroup.WebGL);
      When set to 0, firefox used +/- 30mb less.
    • I notice that every time I start the browser and load the game, the memory consumption has a deviation of +/- 50mb, so it is hard to remove some aspect from the game and conclude that it made a difference.
    • When the webconsole says "successfully compiled" I'm only at 600mb private bytes, it grows then when we start loading assets via assetbundles
    • According to this plugin: https://addons.mozilla.org/nl/firefox/addon/tab-data/ the tab where I have my game running only uses 760mb (while the total is at 1700mb, so where does the 1GB come from?)

    So I wondered if anyone has some advice on how to address this? Can I somehow pinpoint what part of the code takes the most memory? Can I find a memory dump somewhere that I can try to make sense of? Can I add debug logs with information on anything outside the unity heap? Does firefox provide some insight in its memory consumption, or chrome?

    I realize this is a difficult question, any help is really appreciated!

    Thanks!
    Alex
     
  2. Marco-Trivellato

    Marco-Trivellato

    Unity Technologies

    Joined:
    Jul 9, 2013
    Posts:
    1,654
    can you try to open a "about:memory" tab ? That will give you a breakdown of memory usage in Firefox.
     
  3. diekeure

    diekeure

    Joined:
    Jan 25, 2013
    Posts:
    221
    Wow, eye-opener :) Exactly what I needed,thanks! I'll tinker with that for a while.
     
  4. diekeure

    diekeure

    Joined:
    Jan 25, 2013
    Posts:
    221
    One thing that I notice, this subreport:

    1,671.48 MB (100.0%) -- explicit
    ├────876.59 MB (52.44%) ── heap-unclassified
    ├────495.20 MB (29.63%) ++ window-objects
    ├────161.52 MB (09.66%) ++ js-non-window
    ├─────47.95 MB (02.87%) ++ heap-overhead
    ├─────36.92 MB (02.21%) ++ (22 tiny)
    ├─────34.98 MB (02.09%) ++ webaudio
    └─────18.32 MB (01.10%) ++ storage

    Tells me that more than 50% of the memory goes to things he can't classify :(

    In the window-objects I have these two:

    │ │ │ │ │ │ ├──344.83 MB (20.63%) ++ class(ArrayBuffer)
    │ │ │ │ │ │ ├──116.52 MB (06.97%) ++ class(AsmJSModuleObject)

    Anything I can do to make these smaller? Is the arraybuffer caused by using too much Linq for example?
     
  5. diekeure

    diekeure

    Joined:
    Jan 25, 2013
    Posts:
    221
    From what I read in the emspcripten docs, the arraybuffer is where the Unity heap is, right? (I allocated 256mb for this test)
     
  6. diekeure

    diekeure

    Joined:
    Jan 25, 2013
    Posts:
    221
    With the developer edition of firefox there's only 11% unclassified, so that's better (same size though).

    Most of the memory (32%), next to the window-objects I mentioned before, goes to js-non-windows in many small things like

    compartment([System Principal], resource://gre/modules/xxx.jsm

    I guess these are all firefox internal java scripts and so I won't be able to optimize much I'm afraid.
     
  7. diekeure

    diekeure

    Joined:
    Jan 25, 2013
    Posts:
    221
    And another observation: Chrome uses less memory on one subprocess (1.4GB) but in total about the same as firefox. In Chrome there is a spike while loading up until 3GB that sometimes makes it crash.

    Edge runs the game with 2.3GB on memory and loads extremely slow.

    I guess I may conclude from this that these differences are all in the browser handling the javascript and out of my hands to optimze.
     
  8. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,666
    Pretty much, yes. FWIW, If you are concerned with the code size and the memory used to parse the code, that is mainly an issue in Chrome (the initial spike you mentioned, which indeed can cause crashes). Firefox uses asm.js which is much more efficient in memory usage. When looking at Edge, that also supports asm.js as well:

    https://blogs.windows.com/msedgedev/2015/11/10/supercharging-javascript-performance-with-asm-js/

    I think it is not *yet* enabled by default, but they plan to switch very soon, so I suggest you test with that option.
     
  9. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    Jonas, beyond the recent 'fix' in v46, do you have any insight as to whether or not the Chrome team is actively working on addressing these memory issues? I assume it is the difference between v8 and asm.js?

    Thanks.
     
  10. kognito1

    kognito1

    Joined:
    Apr 7, 2015
    Posts:
    331
    For Edge (after the November update), asm.js is no longer listed under experimental features (about:flags) and I think it's enabled by default (seems fast?).

    I can't be sure though because Edge (I think) disables asm.js when the console is open (I get the message: "asm.js has been disabled as the script debugger is connected. Disconnect the debugger to enable asm.js"). It seems to use a lot more memory (and is a lot slower) when I have the console open. It's not clear though that's a result from asm.js being disabled or from the script debugger being active (or both).
     
  11. diekeure

    diekeure

    Joined:
    Jan 25, 2013
    Posts:
    221
    Still working on this, I have made quite some improvements in the way we handle asset bundles. At least the unity heap isn't as full as it used to be.

    However it didn't change anything for the memory footprint of the browser. Ans when I upgraded to 5.3 Firefox takes 2.4 GB instead of 1.8 GB memory. So I still would like to tackle this, I can't release our game with this kind of memory footprint.

    I'm reading in the emscripten docs that we can separate the asm.js to avoid memory spikes. Is this possible? Can I flag --separate-asm? Will I have to change something to the UnityLoader.js file?

    Thank you,
    Alex
     
  12. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,666
    This is correct. Latest Edge has asm.js enabled by default, but not when the console is open.