After trying to understand why some of my Web application's objects were retained in memory by Chrome I think I may have narrowed it down to a case of an otherwise unreachable MediaRecorder object being retained by the browser. Please observe the following minimal example that reproduces the issue (analyzing the heap snapshot after agreeing to share my camera and microphone, which is when the promise returned by getUserMedia resolves).
navigator.mediaDevices.getUserMedia({ video: true, audio: true}).then(function create_media_recorder(stream) {
new MediaRecorder(stream);
console.clear();
});
The media recorder object is not referenced by anything and should have the shortest lifetime it may ever have, yet it is there in memory afterwards in the snapshot I take after the console is cleared (the developers behind Developer Tools recommend clearing the console before taking a heap snapshot because the former may hold on to objects that otherwise would be released).
A possible indication of the fact that Chrome does not release the media recorder object is the red recording icon in the tab title that usually indicates an ongoing media capture by the tab.
I can't find any methods in the MediaRecorder class that would indicate to me one can disassociate it from a stream or otherwise "close" it. Short of making sure there are no obvious or not-so-obvious (e.g. through event listeners) references to it, I can only hope that an anonymous object isn't retained, and such objects usually aren't, but MediaRecorder objects seem to be. There doesn't seem to exist any lever for me to pull to dispose of one, so to speak.
You can see in the screenshot below that what objects retain the media recorder aren't exactly part of my scripts, they rather seem to be related to some internal browser state:
The tiny window icon next to the object selected in Constructor column has the tooltip "User object [is] reachable from window". The snippet above is the only code I run in the tab, why would the object be reachable from window, and if it is, it surely cannot be any references I manage?
So why is the object retained? The bigger problem here is that if my application initiates many recordings and creates a new media recorder object for each, these objects will just keep piling up in memory, a de-facto case of memory leaking.
I've run the same code in Firefox 62.0.2 and there the behavior is what I would expect -- the single MediaRecorder object I created seems to go out of scope (as it should being how it should have no references to it) shortly after it is created and the light indicating my Web camera is in use disappears.
(Chrome version 69.0.3497.100, x64 on Windows 10)
from Why does Chrome retain an anonymous MediaRecorder object in memory?

No comments:
Post a Comment