涉及全局变量时Javascript中的垃圾收集

时间:2014-07-10 03:14:16

标签: javascript html5 audio garbage-collection

所以我正在构建一个带有html5的新<Audio>标签的音频播放器,但我在javascript(See example here)中声明,初始化和操作<Audio>序列。 <Audio>标签一次只允许播放一首歌并轻松操作,因此每当“下一步”,“上一首”,“随机播放”或甚至只是选择另一首歌时,我都会替换{带有新网址的音频标记的{1}},包含新歌。

加载后,我将变量src声明为:

song

所有其他选定的歌曲只是覆盖了var song= new Audio("url"); ,如此:

song

该方法已经结束,但对于每个歌曲实例,事件处理程序监视诸如用于清理的range之类的事件及其属性song= new Audio("new url"); ,它确定范围的长度和值确定索引落在范围上的位置与max的每个先前实例相关联。我不得不重新分配事件监听器并每次重新分配这些属性,在一定数量的歌曲之后,性能确实开始受到影响。

我的问题是,即使javascript有一个垃圾收集器,目标内存不再使用,song的实例都有与之关联的全局事件监听器,所以我认为它们不会被自动删除。一旦歌曲被覆盖,有没有办法删除它们?是否有完全不同但更好的方法来实现我想要的东西?

感谢您提供任何帮助和建议!

2 个答案:

答案 0 :(得分:1)

我决定对问题采取不同的方法,以便完全避免垃圾收集问题。虽然这不一定是我问题的直接答案,但它是一种替代的,有效的解决方案。

我最终只是简单地重新分配audioInstance.src,假设用新的实例覆盖每个Audio实例,其中包含一个新的网址src。最初,歌曲无法播放,或者涉及元数据的自动播放器的某些部分无效,但我找到this链接,这说明您必须先调用audio.load();当您更改{{ 1}}。

此:

audio.src

而不是:

var audio =  new Audio(url);
addListeners(); //only need to do this once, since the listeners always point to audio declared above
var duration=audio.duration;
audio.play();
audio.src = newurl;
audio.load();
duration=audio.duration;
audio.play();

这帮助我达到了我想要的最终结果,摆脱了为var audio = new Audio(url); addListeners(); var duration=audio.duration; audio.play(); audio = new Audio(newUrl); addListeners(); //need to do this a second time, since the old listeners will always be attached to the old audio instance duration=audio.duration; audio.play(); 对象的多个实例声明多个侦听器时出现的垃圾收集问题。

答案 1 :(得分:0)

一旦变量不在范围内,变量将被垃圾收集。 关于全局变量的糟糕之处在于它们永远不会有资格进行垃圾回收。我最好的建议是避免全局变量,并始终将范围限制在所需的范围内