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

kom*_*iga 25 javascript garbage-collection

我有一个js函数,可以使用Audio接口播放任何给定的声音(为每个调用创建一个新实例).

这很有效,直到大约第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>
Run Code Online (Sandbox Code Playgroud)

我也有这个,适用于少于32个playSound调用的页面:

var AudioPlayer = {
    cache: {},
    play: function(url) {
        if (!AudioPlayer.cache[url])
            AudioPlayer.cache[url] = new Audio(url);
        AudioPlayer.cache[url].play();
    }
};
Run Code Online (Sandbox Code Playgroud)

但是这对我想做的事情不起作用(用其他内容(来自单独的文件)动态替换div,它们上面有更多的声音 - 1.内存使用量很容易飙升,2.许多声音永远不会播放).

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

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

Mar*_*pel 20

我看到至少一个(或两个)缺陷:

snd = new Audio(url);
Run Code Online (Sandbox Code Playgroud)

没有var在它前面,所以snd被分配到全球范围.这通常不是你想要的:它使全局名称空间snd变得混乱,如果另一个脚本(例如,扩展名)偶然使用,事情就会变得一团糟.

这也是原因

delete snd;
Run Code Online (Sandbox Code Playgroud)

不起作用:您无法删除全局变量:

当声明的变量和函数成为Variable对象的属性 - Activation对象(对于Function代码)或Global对象(对于Global代码)时,这些属性是 使用DontDelete属性创建的.

所以,使用

var snd = new Audio(url);
Run Code Online (Sandbox Code Playgroud)

代替.顺便说一下,你不能强制JavaScript引擎进行垃圾收集.

  • 这不是真的!您可以通过`delete window.snd`删除全局变量; (2认同)

Dan*_*llo 17

这不是一个详尽的答案,但对于"有没有办法强制chrome js引擎进行垃圾收集?"这个问题,一个chromium.org的人回答说:

一般来说,没有,按设计.出于测试目的,您可以在命令行上传递一个标志,以启用javascript命令"window.gc()"来强制进行垃圾回收.

--js-flags '--expose_gc'


更新:但是,正如@ plash在下面的评论中指出的那样,此标志仅适用于调试版本.

  • 该标志在发布版本中起作用(crbug.com/100875).但我认为你错了.尝试:chrome --js-flags =' - expose_gc' (5认同)