我有一个js函数,用于使用音频界面播放任何给定的声音(为每个调用创建一个新实例)。
这很有效,直到大约第32次通话(有时更少)。此问题与Audio实例的发布直接相关。我知道这是因为我允许时间让Chromium中的GC运行,这将允许我再次播放32个左右的声音。
以下是我正在做的一个例子:
<html><head>
<script type="text/javascript">
function playSound(url) {
var snd = new Audio(url);
snd.play();
snd = null;
}
</script>
</head>
<body>
<a href="#" onclick="playSound('blah.mp3');">Play sound</a>
</body></html>
我也有这个,适用于少于32个playSound调用的页面:
var AudioPlayer = {
cache: {},
play: function(url) {
if (!AudioPlayer.cache[url])
AudioPlayer.cache[url] = new Audio(url);
AudioPlayer.cache[url].play();
}
};
但是这对我想做的事情不起作用(用其他内容(来自不同的文件)动态替换div,它们上面有更多的声音 - 1.内存使用量很容易飙升,2。许多声音永远不会播放)。
我需要一种立即释放声音的方法。是否有可能做到这一点?我没有找到音频接口的免费/关闭/卸载方法。
页面将在本地查看,因此声音的恒定加载根本不是一个重要因素(大多数声音都很短)。
答案 0 :(得分:20)
我发现至少有一个(或两个)缺陷:
snd = new Audio(url);
前面没有var
,因此snd
被分配到全局范围。这通常不是你想要的:它使全局名称空间变得混乱,如果另一个脚本(例如,扩展名)偶然使用snd
,事情就会变得一团糟。
这也是为什么
delete snd;
不起作用:你不能delete global variables:
声明变量和函数时 成为Variable对象的属性 - 激活对象(for 功能代码)或全局对象(用于 全局代码),这些属性是 使用DontDelete属性创建。
所以,使用
var snd = new Audio(url);
代替。顺便说一句,你不能强制JavaScript引擎进行垃圾收集。
答案 1 :(得分:17)
这不是一个详尽的答案,但问题是“有没有办法强制chrome js引擎进行垃圾收集?”,a chromium.org guy replied:
通常,不是,按设计。出于测试目的,您可以传递一个标志 在命令行上启用javascript命令“window.gc()”强制执行 垃圾收集。
--js-flags '--expose_gc'
更新:但是,正如下面评论中提到的@ plash,此标志仅适用于调试版本。
答案 2 :(得分:2)
删除并将其设置为null对我来说也不起作用,所以我做了一个解决方法。
我同时为多个声音工作。要释放实例,每个声音都需要是对象标记。动态地,将每个对象标记(声音)附加到Div。要释放实例,请从Div。
中动态删除对象标记(声音)我猜测这是有效的,因为浏览器通常将每个标记实现为某种对象。因此,当我删除标记时,内部对象将被删除并释放与其关联的所有资源。
<!--HTML: This will contains object sounds-->
<Div id="sounds"></Div>
//Javacript, using jQuery
//Create and play an MP3
var id_event = 1234; //Keep and incrementing a counter might do, I use an Event Id from my app.
var objSound = "<object width='1' height='1' id='AUDIOIE" + id_event
+ " type='application/x-oleobject' AND_MORE_PARAMS_TO_PLAY_A_MP3"
+ "/>";
$(objSound).appendTo('#sounds');
对于完整的对象参数,请转到here。
//To Stop an MP3 and release it instance.
$('#AUDIOIE' + id_event).empty().remove();
答案 3 :(得分:0)
请使用: 让 snd = 新音频(网址);
这样做,分配给变量的内存将在堆内存中, 对于您创建的所有实例,而不是在堆栈内存中,这最终会使您的系统减慢到必须等待 GC 清除它的程度。
根据javascript的内存模型,大多数变量声明应该使用let或const。
var 应该在最罕见的情况下使用。