How should a web-audio-api AudioNode be cleaned up so that its memory is released? I am calling oscillatorNode.stop() and oscillatorNode.disconnect() based on this post, but it doesn't seem to help, and I end up with memory leaks. This post doesn't apply because I'm removing the references as soon as I stop the oscillatorNode.
I created a sample website that shows the issue. Here are the steps to reproduce.
- Create a local html file and run the below code snippet in chrome on a desktop or laptop with dev tools open.
- Create a heap snapshot.
- Click the "Go" button.
- Periodically create another heap snapshot.
- Notice that the memory keeps rising, even after running the garbage collector. Why?
<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>

