Gigabytes of memory leaks when removing twitch embeds

Removing an element with a twitch embed will leak its entire memory usage. Even if there is no listener.

I’ve made an example with two buttons. You can click the “Play” button to show a stream, get a heap snapshot, then hit “remove” to see the new memory usage. Rinse and repeat to see you lose 90MB each time.

https://jsfiddle.net/ubershmekel/kew80vbj/2/

For posterity - this is the full code in that snippet:

HTML:

<script src= "https://player.twitch.tv/js/embed/v1.js"></script>
<button id="playit">Play</button>
<button id="removeit">Remove</button>

JS:

document.getElementById('playit').onclick = function() {
  var div = document.createElement('div');
  div.id="PLAYER_DIV_ID";
  document.body.append(div);
  var options = {
      width: 854,
      height: 480,
      channel: "twitchpresents",
  };
  var player = new Twitch.Player("PLAYER_DIV_ID", options);
}

document.getElementById('removeit').onclick = function() {
  var x = document.querySelectorAll('#PLAYER_DIV_ID')[0];
  x.parentElement.removeChild(x);
}

Alongside that 4 twitch embeds leak about 1 MB of memory per minute. That means 1.4GB per day just for running at all without replacing any stream.

This has caused me to write all kinds of hard-reloads in my webapp: http://ubershmekel.github.io/twitchn/?panels=4&game=Heroes+of+the+Storm

But it still doesn’t prevent Chrome from crashing once in a while because the process itself is having trouble cleaning up some of the things that are happening in a twitch embed.

Please help.

Tested on Chrome 56.0.2924.87 (64-bit), Windows 10.0.14393 Build 14393

Note I’ve posted this issue to github as well at https://github.com/justintv/Twitch-API/issues/679

1 Like

Whether DOM elements are actually removed when they’re removed from the visible DOM tree is up to browser implementation. This means javascript can’t actually force a DOM element to be garbage collected. It’s up to the browser.

The Core DOM APIs are designed to be compatible with a wide range of languages, including both general-user scripting languages and the more challenging languages used mostly by professional programmers. Thus, the DOM APIs need to operate across a variety of memory management philosophies, from language bindings that do not expose memory management to the user at all, through those (notably Java) that provide explicit constructors but provide an automatic garbage collection mechanism to automatically reclaim unused memory, to those (especially C/C++) that generally require the programmer to explicitly allocate object memory, track where it is used, and explicitly free it for re-use. To ensure a consistent API across these platforms, the DOM does not address memory management issues at all, but instead leaves these for the implementation. — https://www.w3.org/TR/DOM-Level-2-Core/core.html

What you can and should do, instead of creating a new player and containing div each time the play button is clicked, reuse the player. See https://jsfiddle.net/kew80vbj/7/ for a basic rewrite of your fiddle using this technique.

Thanks for the report! We’re deploying a fix to remedy this as much as possible. Should be in production in a few hours.

2 Likes

Thank you 3ventic and DallasNChains. I’m reusing the players now instead of creating new ones. Memory usage isn’t exploding anymore. It’s still high and hopefully can be improved in the future but this is already a great improvement. Thank you for your help.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.