requestAnimationFrame garbage collection

2019-01-13 14:01发布

问题:

I'm profiling the following code's memory usage using the Timeline in Chrome Dev Tools v27.

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv='content-type' content='text/html; charset=UTF-8' />
  <title>RAF</title>
</head>
  <body>
    <script type='text/javascript' charset='utf-8'>
      var frame = function() {
        window.webkitRequestAnimationFrame(frame);
      };
      window.webkitRequestAnimationFrame(frame);
    </script>
  </body>
</html>

Notice it's simple. But eventually I see the a tooth pattern appear that indicates the garbage collector is reclaiming memory.

Does raf create garbage objects by default? Is there any way to avoid this? Thx.

回答1:

i think Chrome may have an issue there...

similar bug is already reported here:

https://code.google.com/p/chromium/issues/detail?id=120186



回答2:

I have found out the following: If you change your RAF function into two "ping-pong" like functions, you get alot less garbage. You can't avoid the first initial "big GC", but after that you see only minor GCs of about 50kb instead of 700kb-1mb GCs. The code will look like this:

<script type='text/javascript' charset='utf-8'>
  window.frameA = function() {
    window.webkitRequestAnimationFrame(window.frameB);
  };
  window.frameB = function() {
    window.webkitRequestAnimationFrame(window.frameA);
  };
  window.webkitRequestAnimationFrame(window.frameA);
</script>

I guess this is the best you can do in Chrome. I noticed that in FF the gc intervals or memory hardly changes, so its probably related to the chrome debugging stuff (see the linked chrome bug report above for more details). However, I noticed an improvement in my own game when deploying RAF like this - and heck I need to be able to debug it without artificial GCs that won't happen on normal users machines.



回答3:

It looks like a retain cycle. Frame is calling itself so holds a retain count and doesn't get released. Also any time you are monitoring running code either with profile, timeline or heap stacks there are going to be some side-effects.

Either way I wouldn't worry about it. There are much larger issues to address if you're trying to get your app or page performant. As long as JS completes in under 16ms, no one will ever notice anything.

The biggest memory/CPU issues are: network calls, decompressing PNGs/JPGs, creating and destroying DOM elements, processing/parsing data on a non-worker thread, poor use of GPU textures and allocating lots of data to cause the GC to take a long time to collect data.

I was able to optimize a scroll list with 1,000,000 items to run at 120FPS on chrome (https://github.com/puppybits/BackboneJS-PerfView). The performance tools should help you find the largest issues that the user can see and you don't need to worry about the minor things.