NWJS Audio Memory Leak

  • TLDR; in NWJS, when playing the same set of sounds over and over again over a period of time, used memory will increase (potentially infinitely) until it affects performance.

    The following pertains to EXE's exported with NWJS from Construct 2. C2 and NWJS are updated to the latest versions.

    When playing audio, it appears that some sounds get "stuck" in memory and stack up over time. After a long time in a complex game with lots of audio, this results in slowing down the framerate.

    I've tested with sound files that are (A) stored in the exe, and (B) stored externally. For external audio, you can use Audio - Unload All to bring memory and framerate back to normal, but using Audio - Unload by name for each sound file does not help.

    I've created a test capx with internal sound files and buttons which manually preload and unload external sound files. There are two buttons which toggle randomly playing these sounds extremely rapidly. One only plays internal sounds, the other only plays external sounds.

    In the following tests I took note of the Memory in MB via Windows Task Manager. There are inconsistencies sometimes when running these tests, but my findings in general are listed below:

    1) CONTROL - Run the EXE and do nothing for 5 minutes.

    Results: Memory starts at 75mb, after 5 minutes memory ends up at 73mb.

    2) Run the EXE, Preload external sounds, Play external sounds rapidly for 5 minutes.

    Results: Memory starts at 72mb, after 5 minutes memory ends up at 92mb.

    Addl notes: Unloading sounds manually (by name) does not decrease memory usage. Unloading ALL sounds DOES decrease memory usage.

    3) Run the EXE, Play internal sounds rapidly for 5 minutes.

    Results: Memory starts at 72mb, after 5 minutes memory ends up at 94mb.

    Addl notes: Unload Sounds (by name) and Unload All Sounds both have no effect on memory.

    Letting the test run longer than 5 minutes shows the memory increase further, I did not see a maximum in my testing.

    This seems minor when looking at this small test EXE, but with a big project with hundreds of sounds effects and music, this becomes a problem where memory can increase in the hundreds of megabytes over 10 minutes of play and negatively affect framerate. In my actual game, memory increased from 200mb to 2200mb over the course of 20 minutes of play, and framerate dropped to 30fps. Using Unload All Sounds fixes the problem temporarily, but I cannot use that during normal play for game audio quality reasons, and Unload Sounds (by name) has no beneficial effect to memory or framerate.

    Capx and audio files:

    drive.google.com/file/d/1iGf_hWjeu6EfqG3XIihX7dJycuROU71_/view

    Put the audio files in a folder titled "data" in the same folder as the exported EXE. Let me know if you have any questions, and thank you for your time.

    Edit: I did some additional testing. It appears that if you Preload external sounds, toggle them on for a few minutes until memory increases noticeably, then toggle the sounds OFF and wait a few seconds, then neither of the Unload commands do anything for the memory. So it appears that the Unload commands only affect currently playing sound files?

    Note: If you'd like to more quickly see results in your test, add "Repeat x times" to the code as shown in this linked image:

    drive.google.com/file/d/1wCN1RGmTJJ-wyAY9le1WU49ipEByRr5p/view

  • When you say it's an NW.js memory leak, is that because you tested Chrome and it did not reproduce there?

  • Correct, I tested in both Firefox and Chrome, and this only happens in NWJS.

  • The Audio plugin was not designed to play external sounds at all. I had no idea that the "Play (by name)" action would even work like that if you passed it an external path, so this is, at least at the moment, a totally unsupported case that only works by accident. So I'm not surprised that there would be issues if you use it like that.

    Why do you need to play audio files externally like that? Why not just add them to the project? That is a supported way of playing audio and so the memory management should work correctly.

  • Our project can't work like that, unfortunately. :( Our systems depend on loading all images/audio externally. This particular case impacts the music made using our sequencer: twitter.com/jaytholen/status/949335504646033408

    It will be released along with the page builder for players to make their own songs. We also have custom SFX themes for the OS, as well as a soundscape generator that pulls from external directories.

    The trailer is here so you get a better idea of the broader picture: youtube.com/watch

  • Well I think this is more of a feature request to add a properly supported feature to load external audio files. At the moment you're using the "load a project file by name" action which somehow works with a file path in NW.js mode; that's not something that's officially supported right now.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Okay. We'd upgrade to C3 but there are so many facets of this thing that I imagine are unsupported right now that it could be a mess. Do we formally request this somewhere? Also, is it possible to somehow prioritize such a thing so we don't miss our launch window this year? :( We've been at it for 2.5 years now and it's disheartening and scary. I don't, uh, have other prospects for myself financially so I'm practically begging you.

  • We'd upgrade to C3 but there are so many facets of this thing that I imagine are unsupported right now that it could be a mess.

    Have you actually tried?

    BTW I'm away next week, so I'm afraid I won't be responding any further to this until the week beginning June 18th.

  • While it is true that we're doing some unorthodox things with this project that aren't necessarily supported, the fact remains that this problem occurs with internally stored sound files too. You can test this in my provided capx, exported to nwjs, by clicking the internal sounds button. The sounds played there are all stored in the capx itself. I'm not sure, but I would guess if this was fixed for internal sound files, it'd also be fixed for externally loaded files as well :)

  • Ashley Just tagging you in case you didn't see Mike's reply. Hope you had a nice trip! :-)

  • This is a pretty difficult report to deal with.

    - the report involves several different cases and different instructions in different places, making it difficult to follow

    - the project has several buttons and it's not clear which should be clicked in which order for which cases. An ideal repro will run automatically without requiring any user interaction to eliminate wrong inputs affecting the repro.

    - any repro that says something like "wait 5 minutes" means it will take maybe 10x longer to deal with than if you can make a repro that demonstrates the issue within 30 sec. It's common to have to run the repro 30-40 times or more before it's fixed and the difference between seconds and minutes to repro is the difference between a quick fix and potentially spending hours and hours on it, which we can ill afford given the number of reports we get

    - garbage collection is non-deterministic - if you have say 4GB RAM free the browser may simply decide that there's no point wasting CPU time on a garbage collection. You could try clicking the "collect garbage" button in dev tools to see if it's just not gotten round to a collection yet.

    - if it repros in NW.js but not Chrome it suggests that Construct's code is correct (since it works in Chrome) and some aspect of NW.js is leaking, in which case it might be better to file it with the NW.js developers. If you could reproduce it in Chrome though, this would suggest there is a problem with Construct's code and then we might be able to fix it ourselves.

    I think it could do with being re-filed starting from a clean slate and focus on the internal sounds aspect alone (which is the only case the engine intentionally supports as far as I can tell) with clear and concise instructions.

    I tested the repro project in NW.js 0.31 (Chromium 67). I replaced the "every 0.01 seconds" events with "Repeat 10 times", exported to NW.js, ran it and just clicked the "Toggle internal sounds" button. Over a couple of minutes I could not see any evidence of a memory leak. According to Task Manager the memory would sometimes increase to 120mb or so, but then it would drop back down to 100mb or so. This looks like normal garbage collector activity.

  • Hello Ashley,

    I experienced some weird things since the Chrome 66 update, like high engine CPU usage that goes up until 75/95% and causes Audio sounds to not stop, you can't hear them, but they're still playing in the Debug window (I limit sounds to a certain number in my project so there's no more sound at a point). I can't reproduce it in simple project but I can say there's no problem when using NW.js 0.29 (Chrome 65).

    Then I saw this topic, and it may be related to a memory leak or something of this kind. Sorry that I can't reproduce it with simple project and present you something according to the bug report guidelines. I only experience it on my biggest project. I can only send it to you via MP for you to compare between NW.js 0.29 and the newer version.

    Currently I stick to the NW.js 0.29 (for preview and export) for my project to work as it's available to customers on Itch.io and will be soon released on Steam. I've searched the forum for similar problems and found only this one, except for the many problems that occured with the latest C2 versions that are now apparently fixed. I've tried many things to reproduce, I also searched on Chrome forums, but this seems to be way beyond my knowledges. I only see my project not working as it was before, although I did nothing, just updated the NW.js and was forced to do so by the Chrome browser.

    Thanks

  • Hello,

    Any news about this ? I'm still stuck to NW.js 0.29 with Chrome 65 due to the audio memory leak. It's been three months now. Any tips on the problem or something that can be avoided ?

    Edit : I just found a specific workaround. I was playing lots of unnecessary sounds at layout start, like 200, from function calls during game set up. So I set the sound silent at first, call all functions and then toggle the sound not silent. Then the sounds played further during the game don't trigger the memory leak. It seems that playing too many sounds at once does trigger the memory leak, so it's wise to reduce the number of sounds played at once with the sound tag and a global variable.

    Edit : No way, the problem finally occur after several minutes of playing various audio...

    Ashley ?

  • We need a report following the guidelines to be able to help. This means a minimal project that reproduces the issue, ideally immediately and without any interaction required.

    Further, if the issue is exclusive to NW.js and does not affect any other platforms, then it is probably a bug with NW.js itself. In that case there's nothing we can do about it, so you may do better to report it directly to the NW.js developers. However they will also need a minimal project that reproduces the issue to be able to help.

  • I also noticed this memory leak recently. Haven't done much research into it other than shaking my head in sadness. Anyway, I just wanted to confirm that it's happening to other people as well.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)