Javascript强制GC集合? /强制释放对象?

时间:2010-06-13 22:42:23

标签: javascript garbage-collection

我有一个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。许多声音永远不会播放)。

我需要一种立即释放声音的方法。是否有可能做到这一点?我没有找到音频接口的免费/关闭/卸载方法。

页面将在本地查看,因此声音的恒定加载根本不是一个重要因素(大多数声音都很短)。

4 个答案:

答案 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 应该在最罕见的情况下使用。

相关问题