【问题标题】:What could be causing massive memory peaks in my javascript? [closed]什么可能导致我的 javascript 中出现大量内存峰值? [关闭]
【发布时间】:2012-12-12 11:11:49
【问题描述】:

运行我的代码后,我得到:

每秒多次持续在 4 到 12MB 之间达到峰值。

Here is the full thing.

我已经将它缩小到可能在 draw() 函数或 settarget() 函数中,但我无法弄清楚是什么导致了这么多垃圾。

This is the code

到底是什么导致了这么多垃圾?

【问题讨论】:

  • 看看你在这个脚本上有多少fors。
  • 我在控制台中至少有 10 个错误,也许你应该先检查一下。
  • 为我工作。 @camus - 你在 Chrome 中运行吗?
  • @RicardoLohmann 我知道,但是 for 循环不会产生垃圾。
  • @camus 我只收到两个错误,那是因为它以错误的顺序调用了一个函数。但这并没有破坏任何东西。

标签: javascript html memory optimization


【解决方案1】:

根据我使用Chrome's Heap Profiler 收集到的信息,看起来您正在创建大量数组、数字和字符串。 (对于这样的动画来说,这并不奇怪。)这条线在我看来很可疑:

rgbcolor = 'rgb('+Math.floor(Math.random()*256)+','+Math.floor(Math.random()*256)+','+Math.floor(Math.random()*256)+')';

每个帧上的每个点都会调用它,并创建(至少)一个新的 String 对象,以及 Math 在后台执行的各种与 Number 相关的东西。

也就是说,这会给您带来实际问题,还是只是锯齿状内存配置文件困扰着您?这种内存配置文件对于垃圾收集的运行时并不少见,而且锯齿波的峰值不会随着时间的推移而增加这一事实似乎表明您实际上并没有在任何地方发生内存泄漏。而且,Chrome(和大多数现代浏览器)也非常擅长优化创建此类瞬态对象的代码。

【讨论】:

  • 对我来说没有实际问题,我只是觉得 12MB 内存使用的峰值似乎很高。再说一次,也许不是。另外,我把与颜色有关的那几行代码去掉,设置为#fff,锯齿图案不变。
  • FWIW,看起来垃圾收集器只负责大约 1% 的 CPU(使用 Profiles -> CPU Profile 工具)
  • 好吧,我从来没有真正理解过配置文件工具。好吧,由于内存不会随着时间的推移而增加,我想这不是一个大问题。现在最主要的是它总共使用了我 80% 的 cpu 来运行它。那可以交给gpu吗?
  • 这是一个要求很高的动画,所以我对它使用这么多 CPU 并不感到惊讶。您可以使用 Profile -> CPU Profile 工具来深入了解那里的性能 - 目前这表明 animLoop 和 settarget 是两个 CPU 密集度最高的函数(我期望这并不奇怪)。可能有一些技术可以将一些图形渲染卸载到 GPU,但我不熟悉那个问题空间。我希望它从使用webgl 画布上下文而不是2d 上下文开始。 developer.mozilla.org/en-US/docs/WebGL/…
  • 非常感谢,我会调查的。我将尝试优化 settarget 函数,因为它是 for 循环中的 for 循环,并且每秒总共执行超过 1000 万次检查:/
【解决方案2】:

我实际上认为它在这里:

 window.setTimeout(callback, 1000/60);. 

如果您查看控制台工具中Memory 下的详细信息,您会看到动画帧正在被触发,然后重新触发,然后每隔17ms 重新触发,恰好是1000/60 舍入向上。

您可以打开初始调用:

(function animloop() {
window.requestAnimFrame(animloop);

然后您会看到每个17ms 之后您的进程都会再次产生自己。

【讨论】:

  • 这和内存消耗有什么关系?
  • @broofa 这与内存消耗有什么关系?每次它产生它请求动画帧的过程时 - 它是数百个元素。任何时候你产生任何进程都会消耗内存......
  • 是的,但这就是整个动画的重点。它本质上是一个间隔计时器,你会怎么做呢?
  • 我同意 requestAnimationFrame() 可能是一个更好的设置计时器的 API,但它经过优化(在大多数浏览器中)以 60FPS 运行。所以它不会在这里产生太大的影响。并且 JS 只有一个进程——它没有产生新进程(因此没有与进程相关的开销——它只是将定时器回调排队以安排在下一个 JS 事件循环中。这里的问题不是如何减慢动画,而是如何减少当前动画需求所消耗的内存。
  • @ryan - 峰值是由用户内存消耗和垃圾收集行为引起的。说计时器是原因就像说高油价是由每天早上开车的人造成的。技术上是正确的,但没有帮助。
猜你喜欢
  • 1970-01-01
  • 2020-08-14
  • 1970-01-01
  • 2011-07-27
  • 1970-01-01
  • 2011-10-08
  • 2015-06-12
  • 2010-09-15
  • 1970-01-01
相关资源
最近更新 更多