【问题标题】:Memory leak with web audio api oscillatorWeb 音频 api 振荡器的内存泄漏
【发布时间】:2015-06-09 01:20:49
【问题描述】:

http://codepen.io/superuntitled/pen/EjZOjw/?editors=001

我有一个小的网络工具(见上面的链接)有内存泄漏,我不确定如何插入它。

当一个元素悬停在上面时会调用以下函数(有几百个)。

function tone(id, freq, tonelength) {

  gainNodes.id = audioCtx.createGain();
  osc.id = audioCtx.createOscillator();
  osc.id.connect(gainNodes.id);
  // set frequency and gain
  osc.id.frequency.value = freq;
  osc.id.start(0);

  gainNodes.id.connect(audioCtx.destination);

  gainNodes.id.gain.linearRampToValueAtTime(.1, audioCtx.currentTime);

  gainNodes.id.gain.linearRampToValueAtTime(0, audioCtx.currentTime + parseFloat(tonelength));

}

我认为正在创建重复的振荡器,但不知道如何检查是否是这种情况,或者如何避免这种情况。

我觉得我应该检查一下振荡器是否已经存在,然后运行增益,但我不知道该怎么做。

我试图在振荡器持续时间之后停止它,但这似乎并没有阻止泄漏:http://codepen.io/superuntitled/pen/rVmqYX?editors=001

osc.id.stop(audioCtx.currentTime + parseFloat(tonelength));

对如何做到这一点有任何想法吗?

【问题讨论】:

    标签: javascript memory-leaks web-audio-api


    【解决方案1】:

    osc.id 的东西有点奇怪,因为您将 id 设置为属性名称而不是 osc[ id ] - 但是将这部分放在一边,您希望将其添加到您的底部tone()函数:

    var current = osc.id;
    
    current.stop( audioCtx.currentTime + 2 );
    
    current.onended = function() {
      current.disconnect();
    };
    

    这基本上是说“2 秒后停止播放,完成后,将自己与 AudioContext 断开连接”。

    如果id 被动态分配给osc(例如osc[ id ]),那么您可能还需要delete osc[ id ]——但这似乎只是在每次调用tone() 时都会被覆盖按照你现在的方式 - 所以旧的振荡器应该有资格进行垃圾收集。

    current 变量的原因是,当 onended 触发时,osc.id 可能已被重新分配 - 因此您需要对原始振荡器的引用。

    希望对您有所帮助。

    【讨论】:

    • 严格来说,onended中的断开连接是没有用的。由于OscillatorNodes 无法重复使用,因此当传递给stop 的时间已到时,处理将停止。然后它会被收集并自动断开连接,允许您在代码中删除对它的所有引用。但这是一个细节,它不会有任何伤害。
    • 有道理。我不记得AudioContext.destination 是否持有对连接到它的节点的引用。进一步考虑,很明显这将是一个糟糕的主意。感谢您的澄清。
    • 感谢凯文的帮助,我认为我可以接受并使用它。感谢您在这方面的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-29
    • 1970-01-01
    • 2011-11-06
    • 2016-05-02
    • 2013-09-11
    • 1970-01-01
    • 2021-03-29
    相关资源
    最近更新 更多