reset() does not completely destroy MediaPlayer (memory leak)
Created by: ahfarmer
Environment
-
The MPD passes the DASH-IF Conformance Tool on https://conformance.dashif.org/ -
The stream has correct Access-Control-Allow-Origin headers (CORS) -
There are no network errors such as 404s in the browser console when trying to play the stream -
The issue observed is not mentioned on https://github.com/Dash-Industry-Forum/dash.js/wiki/FAQ -
The issue occurs in the latest reference client on http://reference.dashif.org/dash.js/ and not just on my page
- Link to playable MPD file: https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps.mpd
- Dash.js version: 3.1.3
- Browser name/version: Chrome 86.0.4240.80 & Safari 13.1.2 & Firefox 81.0.2
- OS name/version: Mac Catalina 10.15.6
Steps to reproduce
- Create and initialize a MediaPlayer.
- Call '.reset()' on MediaPlayer
- Notice that many resources are not freed.
See the Leak in Devtools
The above steps will reproduce the leak but you have to look in chrome dev tools at the memory tab. You'll see something like this:
Notice that it looks like getSingletonInstance
is retaining a reference indirectly to a VideoTrackList which will retain the HTMLVideoElement as well.
See the Leak more Easily
I created another way to see the leak here: https://github.com/ahfarmer/dash-mem-leak
Run these commands:
git clone git@github.com:ahfarmer/dash-mem-leak.git
cd dash-mem-leak
yarn install
node bin/modify-dash.js
yarn start
( bin/modify-dash.js
will modify FactoryMaker.js
, adding two console log lines that make it easier to see the issue. )
Then open http://localhost:3000/ and open your dev console. Press the "Recreate" button. This will call reset()
on the current media player and then create a new one.
You will see in the console that I am printing the length of singletonContexts
from FactoryMaker.js
. The count just keeps going up and up, even though I reset my media players before I stop using them, and there is no longer any reference to previous players.
I believe this clearly shows the leak in FactoryMaker.js
. It retains the 'context' for every MediaPlayer ever created. This context indirectly references many other objects, including the HTMLVideoElement that was used. On my site I create & delete MediaPlayers quite frequently (every 5-10 seconds) and our users have reported that their browsers eventually crash.