gpt4 book ai didi

javascript - 网络音频 API 内存泄漏

转载 作者:行者123 更新时间:2023-11-30 14:18:01 25 4
gpt4 key购买 nike

应该如何清理 web-audio-api AudioNode 以便释放其内存?我正在调用 oscillatorNode.stop()oscillatorNode.disconnect() 基于 this post ,但这似乎没有帮助,我最终遇到了内存泄漏。 This post不适用,因为我一停止 oscillatorNode 就删除了引用。

我创建了一个显示问题的示例网站。以下是重现的步骤。

  1. 创建一个本地 html 文件,并在打开开发工具的台式机或笔记本电脑上的 chrome 中运行以下代码片段。
  2. 创建堆快照。
  3. 单击“开始”按钮。
  4. 定期创建另一个堆快照。
  5. 请注意,即使在运行垃圾收集器之后,内存也会不断增加。 为什么

enter image description here

<html>
<body>
<button onclick="go()">Go</button>
<button onclick="cancel=true">Cancel</button>
<div id="status"></div>

<script>
var cancel = false;
var statusEl = document.getElementById('status');

async function go() {
cancel = false;
for (var i = 0; i < 100000; i++) {
if (cancel) {
return;
}
statusEl.innerHTML = i;
play();
await new Promise((resolve) => { setTimeout(resolve, 1); });
stop();
}
}

var ctx = new AudioContext();
var data = {
oscillatorNode: null
};

function play() {
if (!data.oscillatorNode) {
// create an oscillator
data.oscillatorNode = ctx.createOscillator();
data.oscillatorNode.frequency.value = 220.0;
data.oscillatorNode.connect(ctx.destination);
data.oscillatorNode.start(ctx.currentTime);
}
}

function stop() {
if (data.oscillatorNode) {
data.oscillatorNode.stop();
data.oscillatorNode.disconnect();
delete data.oscillatorNode;
}
}
</script>
</body>

</html>

最佳答案

根据 this post ,“当振荡器停止时,它应该自动断开与任何下游节点的连接”。然而,由于 to this bug in chrome (感谢 James Lawruk 找到这个),它实际上并没有自行清理。

This comment从该错误报告中提到

The issue is that because disconnect() is called right after stop(), the oscillator is disconnected from the destination, so any processing associated with stop() is never done. This also includes not actually stopping the oscillator because it takes at least one render quantum to do that. Since it was disconnected, that render quantum never happens.

考虑到这一点,我附加到 oscillatorNode.onended 事件并在该回调中调用 disconnect,不再有内存泄漏!

代码如下:

function stop() {
return new Promise((resolve) => {
//whenever the node actually finishes playing, disconnect it
data.oscillatorNode.onended = function () {
data.oscillatorNode.disconnect();
delete data.oscillatorNode;
resolve();
}
//stop the oscillator
data.oscillatorNode.stop();
});
}

还有堆快照: enter image description here

关于javascript - 网络音频 API 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53241345/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com