-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ensure webaudio is removed from ram/cpu usage #2164
Conversation
@katspaugh @thijstriemstra if (this.backend) {
this.backend.destroy();
this.backend = null;
} |
Your comment on #1940 says we should set this.backend to null but this commit sets this.backend.buffer to null, so which is it :) Your research into the issue is great. if we know loading new audio allows the memory to be garbage collected, we can follow that code path and see what it is doing that we are not doing in the destroy() function. |
Hi, also the audio buffer is already set to null in the I hope that setting the backend to null will resolve all your problems! :) |
Here is something interesting I found that may be a piece of the puzzle... WebAudio createSource sets a reference of the buffer on the source. Line 580 in 658bd92
WebAudio disconnects the source, but never sets it to null. Line 509 in 658bd92
So if when we call destroy() a reference to the backend still exists, then a reference to the buffer will still also exist. Might be part of the problem. And could explain why calling load() again as entonbiba has shown frees the memory, because a new source is set and the old one is collected. I haven't tried setting source to null yet, and it may not be the only case where this happens. |
I found this interesting response on stackoverflow: On destroy we can call also stop() on the source node, if it's playing (in WebAudio). On |
@sundayz lol yes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks. can you also expand the existing test for destroy
and add an assertion that backend
is null
. Also add a changelog entry please (with a reference to the ticket this pr is closing).
@thijstriemstra added null check, @sundayz yes the observation about the |
@entonbiba I meant more somewhere along these lines: https://github.com/katspaugh/wavesurfer.js/blob/entonbiba-patch-webaudio-usage-fix/spec/wavesurfer.spec.js#L351 |
@thijstriemstra I'll add it('destroy', function(done) {
manualDestroy = true;
wavesurfer.once('destroy', function() {
TestHelpers.removeElement(element);
done();
});
wavesurfer.destroy();
expect(wavesurfer.backend).toBeNull();
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work!
I haven't tried the new branch but in my project when I set backend = null, a little bit more memory gets collected but the 50MB arraybuffer still remains there. |
In that case, re-open ticket closed by this pr: #1940 |
@sundayz do you have the code you are using the create the instances ? |
The file is 2000 lines long and it uses Vue so we should test in a code pen :D I will try that tomorrow. I just have a feeling that if the issue was as simple as If your PR fixes the leak for most people then it's still a very good thing. I will try to reproduce the issue without Vue later. Maria had some interesting insights and it might still be worth to set the source to null after disconnecting for example, just to make sure. But that can be done in a separate PR |
@sundayz if it's 2000 lines of vue then it's likely rendering a whole lot more than the audio file that's taking up memory. The best test is to the library without any additional things. I just do ping me when the sample code is available I'll test it as well :) |
Unfortunately this PR introduced a new issue with timing issues around
Commenting out the Basically any code in wavesurfer that relies on the /**
* Get the current playback position
*
* @example const currentTime = wavesurfer.getCurrentTime();
* @return {number} Playback position in seconds
*/
getCurrentTime() {
return this.backend.getCurrentTime();
} This is not necessarily a bad thing, the instance was destroyed afterall, but should wavesurfer fix this (e.g. add a backend !== null check everywhere) or is it up to the user to check for an proper, existing |
Decided it was a valid issue with my tests and this change brought it to light, so no worries, sorry for the noise. |
sounds good |
* ensure webaudio is removed from ram/cpu usage * update changes.md to include ticket katspaugh#1940 * added test for null * remove whitespace
fixes #1940