We are working on making it possible to properly quit the unity runtime and cleanup memory afterwards. The solution we are working on will allow you to quit the unity instance / runtime via either C# or JS: C#: call Application.Quit() JS: call unityInstance.Quit(callback) Note that the JS Quit() is an asynchronous function. The callback parameter is a user-defined onQuit function which will be called when the runtime has quit. In practice, this means you can execute your own custom code: Code (JavaScript): unityInstance.Quit(function() { console.log("done!"); }); unityInstance = null; Alternatively, if you want to Quit from C# and still provide a onQuit callback, you can do that at instantiate-time: Code (JavaScript): UnityLoader.instantiate("unityContainer", "%UNITY_WEBGL_BUILD_URL%", {onProgress: UnityProgress, Module:{ onQuit : function(){ console.log("unity has quit"); } } }); The current fix/implementation will land to 2019.1 and possibly backported to 2018.3. Feedback is welcome.
Neat. "Quitting" the game right now for us means we're loading an empty scene with a GameObject that is looking a Restart message then reloads the main scene. Having a proper way to quit is much welcome.
Is it related to not freed memory bugs after user click close tab in browser? (about crashes when memory not freed in webgl) Or it's specific functionality for close tab?
This sounds great. Are you able to provide detail of how this works under the hood? I'm wondering if this might help with my use case and the issues i've been getting when users are exiting and returning to the application and getting the 'Your browser does not support WebGL' error.
Here is what we do: engine shutdown sequence remove all JS event listeners from canvas, window and document cancel main loop clear all JS intervals delete temporary objects created by UnityLoader remove the canvas
I think that this feature is not working correctly, i have tested it on unity 2019.1.0 beta and here is the code snippet which i am using to quit the application. Code (CSharp): function Quit(){ unityInstance.Quit(function() { console.log("done!"); }); The error description is, i copied my webgl build in wamp server, load the page, then i try to refresh several time the webgl page. After each loading i wait for complete load then refresh the page and randomly chrome get crash with aw snap error while for firefox it produce below error failed to asynchronously prepare wasm: out of memory UnityLoader.js:4:11155 printErr http://localhost/HS2_Testing_Empty_CachingEnable_Unity2019/Build/UnityLoader.js:4 instantiateArrayBuffer blob:http://localhost/519db456-077c-4338-8198-1923f8b0b961:8 out of memory out of memory UnityLoader.js:4:11155 printErr http://localhost/HS2_Testing_Empty_CachingEnable_Unity2019/Build/UnityLoader.js:4 onAbort http://localhost/HS2_Testing_Empty_CachingEnable_Unity2019/Build/UnityLoader.js:4 abort blob:http://localhost/519db456-077c-4338-8198-1923f8b0b961:8 instantiateArrayBuffer blob:http://localhost/519db456-077c-4338-8198-1923f8b0b961:8 The same was happening in older unity version but in new unity even after using the quit method each time, it still show this error.
Additionally thing i want to ask, I tried unity 2018.3.8, you didn't back ported this feature yet? as unity 2019 available in beta format so we can use it in production.
@Marco-Trivellato I have downloaded Unity 2019.1.2 and it is not releasing memory for me, What I did: Create new Project give it a canvas with red bg Build, Add a button: <button type="button" onclick="unityInstance.Quit()">Quit</button> Press the button, memory stays the same, any suggestions? - the render area becomes black - the console shows its calling quit and quitting - memory stays the same Thanks
perhaps you are still holding a reference to the unityInstance. Could you try to assign unityInstance to null after calling Quit() ?
When we use unityInstance.Quit() just like in the exemple or call Application.Quit() from C# we get an exception: Code (JavaScript): Quitting... UnityLoader.js:4 Performance warning: deleting framebuffer on context thread release!!!! UnityLoader.js:4 exception thrown: RuntimeError: memory access out of bounds,RuntimeError: memory access out of bounds at wasm-function[10012]:246 at wasm-function[9732]:28 at wasm-function[6043]:131 at wasm-function[10036]:140 at wasm-function[9673]:271 at wasm-function[9526]:65 at wasm-function[9502]:203 at wasm-function[9443]:387 at wasm-function[9442]:678 at wasm-function[67439]:12 at Object.dynCall_v (blob:https://s3.amazonaws.com/8a416455-e54b-48c8-a074-1639db7347cd:8:493465) at browserIterationFunc (blob:https://s3.amazonaws.com/8a416455-e54b-48c8-a074-1639db7347cd:8:175877) at Object.runIter (blob:https://s3.amazonaws.com/8a416455-e54b-48c8-a074-1639db7347cd:8:178938) at Browser_mainLoop_runner (blob:https://s3.amazonaws.com/8a416455-e54b-48c8-a074-1639db7347cd:8:177400) Tested with Unity 2019.1.4f1.
Same exceptions on Unity 2019.2.1f1: Code (JavaScript): Quitting... UnityLoader.js:4 Performance warning: deleting framebuffer on context thread release!!!! UnityLoader.js:4 exception thrown: RuntimeError: memory access out of bounds,RuntimeError: memory access out of bounds at wasm-function[6732]:403 at wasm-function[6331]:28 at wasm-function[6309]:131 at wasm-function[6981]:139 at wasm-function[6208]:388 at wasm-function[10441]:66 at wasm-function[10417]:206 at wasm-function[10361]:388 at wasm-function[10360]:712 at wasm-function[49506]:12 at Object.dynCall_v (blob:http://localhost:8081/5e9d3e8b-d562-49a6-ba2a-3642efadc5c6:8:489845) at browserIterationFunc (blob:http://localhost:8081/5e9d3e8b-d562-49a6-ba2a-3642efadc5c6:8:183989) at Object.runIter (blob:http://localhost:8081/5e9d3e8b-d562-49a6-ba2a-3642efadc5c6:8:187050) at Browser_mainLoop_runner (blob:http://localhost:8081/5e9d3e8b-d562-49a6-ba2a-3642efadc5c6:8:185512)
Anyway memory is not cleaned up after call Quit(). Everytime i open url or just refresh a page with WebAssembly build, and it allocated memory heap (= Memory size in player settings), tested in Safari (Mobile,Desktop), Chrome, Opera. Only in Firefox it works properly. Tested on empty project in Unity 2018.3.12(doesn't supported Quit()) and Unity 2019.2.1, same issue for both. @Marco-Trivellato any suggestions? Thanks.
Hello @Marco-Trivellato, hello Unity developpers I tried to check what Unity version support the call to the Quit() function. I created a LWRP project (my project uses LWRP), builded to webgl and altered the index.html file by adding in it : Code (JavaScript): <button type="button" onclick="unityInstance.Quit(function() {console.log('quit done!');});gameInstance = null;">Quit Alt</button> I tested with Chrome 78.0.3904.108 2019.1.8 : crash 2019.1.14 : crash 2019.2.15 : crash 2019.3.0 : crash (with a different call stack though) Is there something I'am not doing right in this test ? Do you know if the results depend on the browser version ? Is there another way to deal with quit and memory cleanup ? have a nice day, thanks
In case it could help, here is the call stack whith a development build (Unity 2019.3.0) : 6b452f9a-dc87-4fab-bb4e-42bdf8928c1f:9326 Uncaught RuntimeError: memory access out of bounds at __ZN18GfxFramebufferGLES18ReleaseFramebufferEP17RenderSurfaceBaseP14GfxContextGLES (wasm-function[9165]:0x30c964) at __ZN13GfxDeviceGLES28DestroyRenderSurfacePlatformEP17RenderSurfaceBase (wasm-function[8838]:0x2ee6f0) at __ZN9GfxDevice20DestroyRenderSurfaceER12ObjectHandleI17RenderSurface_TagP17RenderSurfaceBaseE (wasm-function[4852]:0x15098d) at __ZN11ContextGLES22DeleteIntermediateFBOsEv (wasm-function[9189]:0x30f886) at __ZN11ContextGLES7DestroyEv (wasm-function[9273]:0x318ec5) at __ZN13GfxDeviceGLESD2Ev (wasm-function[8779]:0x2ec342) at __Z16DestroyGfxDevicev (wasm-function[8589]:0x2d72b2) at __Z13CleanupEnginev (wasm-function[8490]:0x2ca4e5) at __Z13PlayerCleanupb (wasm-function[8402]:0x2c16b0) at __ZL8MainLoopv (wasm-function[8400]:0x2c14b2) at dynCall_v (wasm-function[51372]:0xd03c66) at Object.dynCall_v (blob:file:///6b452f9a-dc87-4fab-bb4e-42bdf8928c1f:25151:36) at browserIterationFunc (blob:file:///6b452f9a-dc87-4fab-bb4e-42bdf8928c1f:9218:23) at Object.runIter (blob:file:///6b452f9a-dc87-4fab-bb4e-42bdf8928c1f:9320:5) at Browser_mainLoop_runner (blob:file:///6b452f9a-dc87-4fab-bb4e-42bdf8928c1f:9256:20)
And the call stack for Unity 2019.2.15 (this error appears twice in the console log) Uncaught RuntimeError: memory access out of bounds at __ZN18GfxFramebufferGLES18ReleaseFramebufferEP17RenderSurfaceBaseP14GfxContextGLES (wasm-function[5166]:0x16b897) at __ZN13GfxDeviceGLES28DestroyRenderSurfacePlatformEP17RenderSurfaceBase (wasm-function[4687]:0x13d53b) at __ZN9GfxDevice20DestroyRenderSurfaceER12ObjectHandleI17RenderSurface_TagP17RenderSurfaceBaseE (wasm-function[4665]:0x13cdf9) at __ZN11ContextGLES22DeleteIntermediateFBOsEv (wasm-function[5426]:0x1894e0) at __ZN11ContextGLES7DestroyEv (wasm-function[5649]:0x1a47a6) at __ZN13GfxDeviceGLESD2Ev (wasm-function[4562]:0x139055) at __Z16DestroyGfxDevicev (wasm-function[9106]:0x2f9a9e) at __Z13CleanupEnginev (wasm-function[8983]:0x2ed965) at __Z13PlayerCleanupb (wasm-function[8893]:0x2e45c2) at __ZL8MainLoopv (wasm-function[8891]:0x2e43c4) at dynCall_v (wasm-function[46263]:0xc0efef) at Object.dynCall_v (blob:file:///8aa94320-b377-40ca-b05b-ebfecbb36124:24953:36) at browserIterationFunc (blob:file:///8aa94320-b377-40ca-b05b-ebfecbb36124:9014:23) at Object.runIter (blob:file:///8aa94320-b377-40ca-b05b-ebfecbb36124:9116:5) at Browser_mainLoop_runner (blob:file:///8aa94320-b377-40ca-b05b-ebfecbb36124:9052:20)
Oh, it seems there is a huge difference between a LWRP project and Legacy project. Legacy projets are ok (tests made with Unity 2019.2.15 and 2019.3.0)
Porting our project back to Legacy would represent quite an effort... I'am looking for a way to avoid it. Is there a way to create a home made CustomQuit() where LWRP specifics (i don't know precisely what) would be cleared before calling the genuine unity Quit() ?
After more tests, it appears the crash is linked to color space. With color space = gamma, Quit() works But with color space = linear, Quit() crashes I was misled because Legacy project are created with color space = gamma, whereas LWRP projects are created with color space = linear. But LWRP+gamma : no crash and Legacy+linear : crash
add code on index.html Code (JavaScript): window.onbeforeunload = function() { gameInstance.Quit(); gameInstance = null; }; then you can refresh
Hi, thx for all the great job you are doing with unity. I tested Quit() function in webGL build (2019.217f1) and set to null UnityLoader, the instance, the module and the dom element containing the canvas (webgl context) but I noticed that the memory is not released (tested on chrome and firefox). The heap is still full of JSArrayBuffer (see image). I suspect a(some) reference(s) is(are) still pointing to the unityInstance(see image) which avoid the GC to grab unityInstance. I had similar issues when using Threejs, but they expose a dispose() function on geometries (https://threejs.org/docs/#api/en/core/Geometry) and materials which allows to "Removes The object from memory." Calling their function to each objects of the scene solved my problem. I wondering if this Quit function is actually doing a similar thing ? If not, maybe a solution is to call via gameInstance.sendMessage() a "delete" on each object/assets of the unity scene? Does someone manage to release the memory on webGL build? I'm using unity for an hour, so I just wonder if you can give me some hints about such a "delete or dispose" function we can call and if I'm going to the good way. Thx a lot. View attachment 543309
@Marco-Trivellato any news on this? seems that the Quit() function is not releasing memory for a lot of people, including our company, this is a big deal for us since heap fragmentation is impossible to manage in our case that we need to load and unload stuff on memory all the time, we have no memory compaction methods, we have no manual GC options, and we still have no way to at least destroy the unity instance and re instantiate a new clean one because the older one remains using memory of the browser, any ETA's of news on this?
I am having a similar problem with Quit() although it may not be exactly the same, but maybe. I am calling Quit() from JS but if I attempt to run the application again (even with a new browser instance) I get a crash. If I clear the browser cache prior to running the second time it works as expected. It seems like Quit() is not cleaning up something correctly or leaving the cached application in a state that it cannot be run again and a new copy needs to be downloaded (defeats the purpose of a cache). Is this related or should I start a new thread?
@Marco-Trivellato Any update on the issue in the previous post? I'm using the latest 2019.3 release and still encountering the issue of a crash the second time the application is launched. Thanks
For me the issue seemed to be with saving player preferences. I refactored the code so I wasn't doing that and it worked - not ideal but it got me around the issue. The app was originally developed targeting a different platform and I was saving the preferences in a json file. In the WebGL version this is stored in the IndexedDB virtual filesystem and I could see it persisted there but when it tried to read it back it failed. For the use case I was dealing with in WebGL I didn't really need the preferences so I just hobbled the code. At least I can build and run now.
Hmm, we aren't storing anything in player preferences, but we do have a logging system that generates a file into application data path, which on webgl is the IndexedDB. I wonder if anything that writes into IndexedDB causes a problem then.
That was my suspicion. It seems to write to it ok but has a problem reading back, as I was under time pressure I didn't investigate further but would be interested if you find a resolution (other than my just don't use it solution).
Is this feature in a usable state yet? It'd be extremely useful to us. Edit: We can confirm that the Quit() method works and unloads memory, but color space must be set to Gamma. Also we still have general WebGL memory leaks (anywhere from several GB to endless memory climbing, over 30GB!) so this is still an ongoing problem. Edit 2: We found that the memory leaks seem to be occurring through having "double caching" of the asset bundles, from addressables settings. Turning off caching in one place still enabled caching but resolved the memory issues.
I get similar error messages to this when I try to enter fullscreen on Chrome ("Performance warning: deleting framebuffer on context thread release!!!!"), and it also correlates with a bug that makes UI elements with shader graph materials disappear. I get neither the bug, nor the disappearing ui elements when I switch to gamma color space or use non-webgl platforms.
I'm assuming this method is no longer working for Unity2020 ? is there an updated way to do this with the new unity loader?
Application Quit() is supported, but there has been a regression crash observed regarding quitting, which has been fixed in trunk. The fix will land in Unity 2020.1 and newer.
Using Unity2020.2, I am calling (from javascript) Code (JavaScript): unityInstance.Quit(function() { console.log("i want to handle some things here") }); In the console I see: Quitting... done! but not "I want to handle some things here". So perhaps the quitting is working (it doesn't clear or remove the canvas though, but that's fine, at least the game loop is not running anymore and I guess memory is freed up) the callback is not. This seems unintended. Should I file a bug report for this?
Hmm, it looks like the Quit() function has been changed from old style function callbacks to return a modern style Promise. So the correct code would be Code (JavaScript): unityInstance.Quit().then(function() { console.log('i want to handle some things here'); }); I am curious, is there some source where you found the old style code example? I wonder if our documentation is out of date somewhere that we should update?
Thanks for the response, i'll check it out. > I am curious, is there some source where you found the old style code example? I wonder if our documentation is out of date somewhere that we should update? Yes, at the top of this thread, the opening post by Marco-Trivellato
Oh, right! The transition from the old style to the new style occurred in 2020.1, where the the Unity loader was largely rewritten.
I created this basic project in Unity 2020.2.0b7 to test out the quit function. But it doesn't seems to clear out the memory. Link: https://webglmemoryleak.000webhostapp.com/index.html Also the Application.Quit (the button in the scene) seems to have little effect on the memory. My code looks something like this: Code (CSharp): quitButton.onclick = function () { unityInstance.Quit().then(function () { unityInstance = null; container.remove(); }); } }
This is a known issue that has been fixed recently in our trunk branch. I do not yet know when the fix will make its way in Unity 2020.2 unfortunately. (Hopefully in 2020.2.0b8, but not 100% sure)
This issue is still happening yes? What is the latest fix? We are experience a crash when the user does anything that unloads unity. here is our quit code in .js Code (JavaScript): UnityContext.prototype.quitUnityInstance = function () { var _this = this; if (typeof this.unityInstance !== "undefined") this.unityInstance.Quit().then(function () { _this.invokeEventListener("quitted"); _this.unityInstance = undefined; }); };
Unity 2020.2.2f1 and 2021.1.0b3: unityInstance.Quit() run without errors, but not working. Memory still filled
We are not currently tracking any further memory leaks after the original memory usage fix. When profiling any memory usage issues, remember the following two points: 1. do not have any of the DevTools windows open (Console, Inspector, Network, Memory, etc.), these pin down memory from being able to garbage collect. (when looking at Memory tab, first have it closed, and then only at the very end of the test run open it up) 2. browsers do not eagerly free up memory, but instead it occurs lazily after dozens of seconds or even minutes. This is the way that incremental garbage collection works. If you are still getting memory leaks after patiently observing, and avoiding 1. and 2., then try doing a Memory snapshot and report it here.
This is how I start the application: Code (JavaScript): var cnv = document.createElement('canvas'); cnv.setAttribute("id", "unity-canvas"); cnv.className = "unity-canvas"; createUnityInstance(document.querySelector("#unity-canvas"),{...}).then((unityInstance) => {_this.unityGame = unityInstance;}); This is how i close app: Code (JavaScript): _this.unityGame.Quit().then(function () { _this.unityGame= undefined; var element = document.getElementById('unity-canvas'); element.parentNode.removeChild(element); }); Each time the application is launched (after closing the previous one), the browser page increases in RAM. As a result, the page crashes after a while. Waiting for 30 minutes does not clear memory. I did not use development tools, only Windows task manager. This example also shows this. Google Chrome never clear memory, in Firefox sometimes it works. I'm attach chrome's memory snapshot
Thanks for the link. Here is my test: 1. Open the page https://webglmemoryleak.000webhostapp.com/index.html 2. Check memory usage: it sits at 1.1MB 3. Load Unity once 4. Close it. 5. Check memory usage: it sits at 158MB. Browser has not garbage collected it yet. 6. Wait for some time, then check again. Memory usage now sits at 1.4MB. 7. Load and Close Unity page 10 times. 8. Then check memory usage: it sits at 158 MB. (last instance has not been GCd, earlier ones have) 9. Wait for some time, then check again. Memory usage now sits back at 1.4MB. You can find a video of the results attached in this post. This suggests that everything is being freed properly from Unity and Chrome JS browsing context perspective. Tried also to look at memory usage in Windows Task Manager, but did not find an increase there. If memory usage in Windows Task Manager is increasing, but the memory usage inside the JS browsing context (as shown using the Memory DevTool tab) is not, then it is a Chrome issue (and should go to https://bugs.chromium.org/p/chromium/issues/list ) Tested on Windows 10 with Chrome. Would you be able to create a video of what you are seeing?
Your algoritm works fine. But if I don't checking memory in DevTools (taking snapshots), then i get high memory consumption. It feels like the garbage collector fires after checking the memory. Maybe I'm crazy Please, check your test again without snapshots. After ~40 times and waiting 15 minutes, without checking memory i have this (Every try adding thread):
Reported the issue to Chromium bug tracker on your behalf. Maybe CC yourself to that bug, and if you can, record a video that showcases the memory leak on your system? See the bug report here: https://bugs.chromium.org/p/chromium/issues/detail?id=1174533
I can confirm, It's not fully fixed yet. If I don't use any compressions then it seems to be working fine. But if I use these settings for example, then it still will memory leak. I think the problem is in the decompression fallback. GZip + fallback: https://webglmemoryleak.000webhostapp.com/Gzip.html No compression: https://webglmemoryleak.000webhostapp.com/NoCompression.html Here are the original project files if you are interested in that: https://mega.nz/folder/TZNTRS6T#jx-JZEJpnJotszVnWWKvNA
Hey all, I'm running in to the same issue using Firefox on Windows 10. I took the steps described above, and I'll summarize my results here. I've also attached a video of what I am seeing. 1. Loaded the page 2. Checked memory usage: sitting at 1.37mb 3. Load Unity once 4. Close it 5. Check memory usage: sits at 178mb 6. Wait for some time, then check again. Memory usage still sits at 178mb. Does not appear to have been gc'd 7. Load and close Unity several times 8. Check memory usage: sits at 1.3gb. No gc appears to have been done 9. Wait for some time, then check again: memory still sits at 1.3gb. No gc appears to have been done. Let me know if I can do anything different to help test further! Thanks!