【问题标题】:How to prevent memory leak by cleaning up <audio> elements?如何通过清理 <audio> 元素来防止内存泄漏?
【发布时间】:2010-12-05 01:10:42
【问题描述】:

我用 jQuery 编写了一些 JavaScript,它加载了一个带有 HTML 5 &lt;audio&gt; 标签的声音文件,并在鼠标单击时开始播放该声音文件的一个新实例(以便它可以并行播放多次/覆盖)。

HTML:

<audio id="audiotemplate" src="audio/myfile.ogg"></audio>

JavaScript:

mybutton.click(function() {
    $('#audiotemplate').clone()[0].play();
});

这按预期工作,但会造成内存泄漏,导致 FF 耗尽系统 RAM,并且如果您单击该按钮太多次,Chromium 会显示其“啊,快拍”页面。

编辑:为了快速测试,最好使用$(document).keypress 而不是mybutton.click,并按住按钮。

声音文件播放完毕后如何清理&lt;audio&gt;元素?

注意:我不会将克隆的元素插入到页面中。

注意 2:如果您单击也会发生泄漏,等到声音结束,再次单击...

(我对解决方案感到满意,但也感谢解释为什么会发生泄漏。)

【问题讨论】:

  • 游戏有点晚了,但你为什么要克隆它们,而不是暂停/播放剪辑? var sound = $('#audiotemplate')[0]; sound.pause(); sound.currentTime = 0; sound.play(); - 此代码将暂停剪辑,将其重置为 0 并再次播放。唯一需要注意的是你不能在播放之前设置 currentTime,所以你需要一个 if 语句来检查它是否已经播放了。
  • @Gavin 因为有时它们需要重叠播放(这最初来自于在按键上播放某些东西)。
  • 我最近遇到了类似的问题,暂停/重置时间并再次播放效果很好,无需克隆任何东西?现在没关系,但认为它可能值得其他人研究?

标签: javascript jquery memory-leaks html5-audio


【解决方案1】:

这样效果更好吗?

mybutton.click(function() {

    var cloned = $('#audiotemplate').clone()[0];

    cloned.play();

    cloned.onended = function() {
        $(cloned).remove();
    }

});

Here on JSFiddle.

我只能猜测泄漏,即为您克隆的每个实例保留了一些内存,并且当它完成时它不会自动清理,因为您可能需要再次访问它。例如,您的浏览器不知道您只想播放一次,所以它会保留它,因为您可能想再次调用play()

使用 jQuery 的 remove() 应该可以释放内存。

更新

你克隆了多少次?您知道这是一个浏览器,并且可能没有针对同时运行数百个 audio 元素进行优化?

我刚刚在 Firefox 3.6 中克隆了它 ~300 ~600 次,它运行良好。不过,在 Chrome 8 上运行了几百次后,它确实崩溃了。

Here it is cloning via setInterval()如果您认为它会导致浏览器崩溃,请不要点击

更新

@alex:不,不是同时。我的问题是,即使声音比重生间隔短(如注 2 所示),Chromium 也会泄漏内存 - 所以不是同时播放,而是一个接着一个播放。

Does this still crash your browsers?

【讨论】:

  • 用户想要多少次都可以,但不会频繁到浏览器崩溃,因为所有声音都在同一时间运行(见注 2)。
  • @nh2 所有这些声音同时运行的目的是什么?
  • 有趣。您的 JS sn-p 导致我的 Chrome 第一次在 ~75 个克隆时开始滞后;随后的负载克隆了 600+ 没有问题,内存峰值大约为 250MB(对于该选项卡),然后几次回落到 25MB 左右(由于垃圾收集)。另外,Do not click 让我无论如何都想点击它,看看会发生什么...... :-)
  • @Cameron 呵呵!好吧,由于某种原因,我的 Firefox 在 OS X 上不会崩溃(谁会想到?),因此优于 Chrome。
  • 你的 snippent 在 99 次后每天都会让我的 Chromium 9 (Ubuntu 10.10) 崩溃。
猜你喜欢
  • 2012-03-14
  • 1970-01-01
  • 1970-01-01
  • 2010-12-20
  • 2010-09-21
  • 2021-07-13
  • 2015-02-05
  • 1970-01-01
相关资源
最近更新 更多