requestAnimationFrame 垃圾回收

30

我使用 Chrome Dev Tools v27 中的时间线(Timeline)对以下代码的内存使用情况进行分析。

<!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>

注意这很简单。但最终我看到了一个牙齿图案出现,表明垃圾收集器正在回收内存。

Chrome Dev Tools时间轴

raf默认会创建垃圾对象吗?有没有什么方法可以避免这种情况?谢谢。


相关。在这个领域似乎存在更多潜在的问题。也许我建议大家对这个内存监控工具的输出持怀疑态度?老实说,我并不确定该从中得出什么结论。https://dev59.com/--o6XIcBkEYKwwoYLhPO - Steven Lu
如果有人愿意做同样的事情,我会在这个问题上设置赏金:>我已经在考虑是否有两个函数交替注册对彼此有帮助。 - Manuel Arwed Schmidt
3个回答

7

enter image description here

我发现以下内容: 如果将您的RAF函数更改为两个类似于“乒乓”的函数,则会产生更少的垃圾。您无法避免第一次初始的“大GC”,但之后只会看到约50kb左右的小型GC,而不是700kb-1mb GC。代码将如下所示:

<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>

我想在Chrome中这是你能做到的最好的。

我注意到在FF中,gc间隔或内存几乎没有变化,因此可能与Chrome调试相关(有关更多详细信息,请参见上面链接的Chrome错误报告)。然而,当像这样部署RAF时,我发现自己的游戏有所改善 - 而且我需要能够调试它,而不需要人为GC,这在普通用户机器上不会发生。


2
我惊讶地说这个可行。真是令人惊奇的发现,我甚至无法想象是什么让你尝试这个的。 :) - Jaruba
1
Kevzettler:这总是一个希望有一天会过时的黑客。你能告诉我们你测试了哪个浏览器版本吗?你是否仍然普遍观察到gc问题?我会相应地编辑答案。 - Manuel Arwed Schmidt

5

3
看起来像一个保留循环。Frame在调用自身,因此保持了保留计数并且没有被释放。此外,无论何时您都在监视运行代码,无论是使用profile、timeline还是heap stacks,都会产生一些副作用。
无论如何,我不会担心这个问题。如果您试图使应用程序或页面性能优化,有更大的问题需要解决。只要JS在16ms内完成,就不会有人注意到任何问题。
最大的内存/CPU问题包括:网络调用、解压PNGs/JPGs、创建和销毁DOM元素、在非worker线程上处理/解析数据、GPU纹理的使用不当以及分配大量数据导致GC花费很长时间来收集数据。
我能够优化一个带有1,000,000个项目的滚动列表,在Chrome上以120FPS运行(https://github.com/puppybits/BackboneJS-PerfView)。性能工具应该帮助您找到用户可以看到的最大问题,您不需要担心次要问题。

嘿!你有没有想过如何在 rAF 动画中使用这个想法? - thednp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接