Memory issues in Chrome? Try Canary

This is an FYI for anyone running into memory issues specific to Chrome (especially Chrome 32-bit) when running Unity WebGL content. Particularly for cases where Chrome runs out of memory by either crashing or throwing an error at startup, which is typically caused by the V8 JavaScript VM using too much memory to parse its AST structure for our code:

Google has come up with a change which significantly decreases the memory usage of the AST parsing. This change is currently in Chrome Canary (but has a chance of being backported to the Chrome beta channel). So if you are affected by these issues, please download Chrome Canary, and let us know if things improve.

2 Likes

Weā€™ve been plagued by this Chrome memory/crash issue: https://code.google.com/p/chromium/issues/detail?id=533648

It seems to be fixed in Chrome Canary!

Hmā€¦ Is it update for all usersā€¦ or only for a developers? ā€¦ Iā€™ll try to update tomorrow

Our WebGL app has been crashing on startup since the 45.0.2454.93 release of Chrome, while Firefox and Safari continue to run the application without fail. Weā€™ve been testing with Canary since then but still hit the ā€œAw, Snap!ā€ error just as the Unity progress bar hits 100%.

Activity monitor shows memory consumption reaching as high as 4.5GB(!) before loading fails. This occurs on machines with 8 or 16GB of memory (both OSX and Windows) so we assume it is not a hardware limitation.

By stripping assets from our application or reducing their size we are able to reduce memory consumption and get the game to load under Chrome, but without those resources its not much of a game!

So now we are faced with the prospect of either waiting for Google to catch up with Firefox and Safari, or hacking up a method do download resources dynamically at runtime, or devising a way of storing assets in a local cache and accessing them from there when needed (if that is even possible).

Any thoughts on how to proceed (or insights from others in the same boat) would be greatly appreciated.

Thanks.

These changes in Canary build will eventually make it to the normal Chrome.

1 Like

wellā€¦thatā€™s not really a hack. itā€™s one of the best practices we recommend so that you only keep assets in memory when you need them. In addition, this will also minimize loading times.

Asset Bundles are the way to go if you want to make content for the web.

Quite right, wrong choice of words on my part.

May I ask, is there a list of best practices for WebGL available? Things to aim for, others to avoid?

Sure!

In terms of best practices that will minimize the chances of Browser out-of-memory issues and Chrome crashes, I think these are some of the important ones:

  • Reduce your code size:

  • Enable Code Stripping

  • Disable Exceptions

  • Try to avoid usage of 3rd party plugins

  • Reduce your Data size:

  • Use Asset Bundles

  • Use Crunch texture compression

  • Reduce the size of the Unity Heap:

  • Keep the ā€˜WebGL Memory sizeā€™ as small as possible

Of course this is just a summary, if you want to know more about them I would recommend you to have a look at this manual page and this Unite talk.

Hope that helps.

4 Likes

Marco is there a strategy for determining how small the mem size can be? In the worst case, would the build crash at load if we set it to small, or crash some unknown amount of time into gameplay?

Thanks!

Yes, the best strategy would be to use the memory profiler and analyse how much memory your content actually requires, then change WebGL Memory Size accordingly.

Letā€™s take an empty project as an example. The Memory Profiler tells me that ā€œTotal Usedā€ amounts to just over 16MB (this value might also differ between releases of Unity). That means I must set WebGL Memory Size that something bigger than that. Obviously, ā€œTotal Usedā€ will be different based on your content.

However, if for some reason you cannot use the Profiler, you could simply keep reducing the WebGL Memory Size value until you run out-of-memory and get this error message:
ā€œOut of memory. If you are the developer of this content, try allocating more memory to your WebGL build in the WebGL player settings.ā€

That basically means WebGL Memory Size is now too small and you need to increase it.

That really depends on your content, however, itā€™s for sure after the initial loading of code and data.
So, for that reason, I suggest you test the entire game whenever you change WebGL Memory Size.

Just a +1 to the canary. Had a client that couldnā€™t access content at all on a 32bit Win system to using Canary and the content ā€˜working flawlesslyā€™ (their words)

@Marco-Trivellato thanks for the tips - indeed we cant use the profiler because we have a facebook canvas app. I have considered creating a crippled version that runs outside of the canvas, but it would be a nightmare to engineer and maintain.

Just an update, using WWW.LoadFromCacheOrDownload in Unity 5.2.1p3 causes the memory crash in Chrome and Canary. The memory behavior is different (Chrome has 2 processes that bloat memory, Canary has one that continually grows until the OS kills the process) but they both are unusable. It forces us to NOT use the built-in Unity cache call.

Likely this is a different issue which we are looking for more information about. Would you mind opening a new thread ?

To anyone still having issues with Chrome using up all available memory and then hard crashing within seconds of loading a WebGL Unity page, Iā€™ve found a solution that can be applied directly to your deployed html5 project files:

From https://code.google.com/p/chromium/issues/detail?id=533648

It appears that inside Release/Html5.js there is a call to the web browsers internal filesystem function FS.syncfs()
And Chrome does not rate-limit calls to this function, so if one call isnt finished yet, it can just call another and another etc. until all memory is exhausted.

The fix is this:

  • Open up Release/Html5.js in a decent text editor that can handle 25mb text files (I used Notepad++)
  • Do a search for _JS_FileSystem_Sync() it should be on line 9, just after HEAP32[params+i>>2]=data*}}}*
  • Replace the existing function with this one:
var syncing_fs = false;
function _JS_FileSystem_Sync() {
  if (!window.indexedDB) return;
  if (syncing_fs) {  return;  }
  syncing_fs = true;
  FS.syncfs(false, (function(err) {syncing_fs = false;}))
}

Now that takes care of the uncompressed Html5.js, youā€™ll need to gzip this file up in order to replace the one in Compressed/Html5.jsgz, I used my Linux box and ran gzip -c Html5.js > Html5.jsgz
That seemed to fix it for me!

@Marco-Trivellato can we get this rolled into the next 5.3 beta? I can confirm that fix works, but its super annoying to have to do it for each build.

Thanks!

There is a problem with this approach where basically you might miss a file system update. For this reason we implemented a different fix in 5.3, which is also being back-ported to 5.2

1 Like

According to Google, the fix this thread is about has now landed in the release version of Chrome 46. Will un-pin this thread now.

If you still run into out of memory crashes specific to Chrome while loading Unity content, let us know and we will inform Google.

Jonas,

Could you please reference the Chrome bug that they say is fixed? #533648 hasnā€™t been updated so Im curious as to which bug (and which 46version) has addressed.

Thanks.

Jonas, Memory Crash still happens for me in Chrome 46 on Windows 7 32-bit OS while trying to load my game here: http://apocalypsecity.net/webgl/ the memory allocation is set to only 160MB, way below the default 256MB. This game runs perfectly fine on my Windows 8 64-bit OS. Still no improvementā€¦ :face_with_spiral_eyes: