Javascript Javascript强制GC收集?/ 强制释放对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3034179/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Javascript force GC collection? / Forcefully free object?
提问by komiga
I have a js function for playing any given sound using the Audio interface (creating a new instance for every call).
我有一个 js 函数,可以使用 Audio 接口播放任何给定的声音(为每次调用创建一个新实例)。
This works quite well, until about the 32nd call (sometimes less). This issue is directly related to the release of the Audio instance. I know this because I've allowed time for the GC in Chromium to run and it will allow me to play another 32 or so sounds again.
这工作得很好,直到大约第 32 个电话(有时更少)。这个问题与Audio实例的发布直接相关。我知道这一点是因为我已经让 Chromium 中的 GC 有时间运行,它可以让我再次播放 32 个左右的声音。
Here's an example of what I'm doing:
这是我正在做的一个例子:
<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>
I also have this, which works well for pages that have less than 32 playSound calls:
我也有这个,它适用于少于 32 个 playSound 调用的页面:
var AudioPlayer = {
cache: {},
play: function(url) {
if (!AudioPlayer.cache[url])
AudioPlayer.cache[url] = new Audio(url);
AudioPlayer.cache[url].play();
}
};
But this will not work for what I want to do (dynamically replace a div with other content (from separate files), which have even more sounds on them - 1. memory usage would easily skyrocket, 2. many sounds will never play).
但这对我想要做的事情不起作用(用其他内容(来自单独的文件)动态替换 div,这些内容上有更多的声音 - 1. 内存使用量很容易飙升,2. 许多声音将永远不会播放)。
I need a way to release the sound immediately. Is it possible to do this? I have found no free/close/unload method for the Audio interface.
我需要一种方法来立即释放声音。是否有可能做到这一点?我没有发现 Audio 接口的 free/close/unload 方法。
The pages will be viewed locally, so the constant loading of sounds is not a big factor at all (and most sounds are rather short).
页面将在本地查看,因此声音的不断加载根本不是一个大因素(而且大多数声音都很短)。
采纳答案by Daniel Vassallo
This is not an exhaustive answer, but to the question "Is there any way to force the chrome js engine to do garbage collection?", a chromium.org guy replied:
这不是一个详尽的答案,但对于“有什么办法可以强制 chrome js 引擎进行垃圾收集?”这个问题,一位chromium.org 的人回答说:
In general, no, by design.For testing purposes there is a flag you can pass on the command line to enable a javascript command "window.gc()" to force garbage collection.
--js-flags '--expose_gc'
一般来说,不,设计使然。出于测试目的,您可以在命令行上传递一个标志,以启用 javascript 命令“window.gc()”来强制垃圾收集。
--js-flags '--expose_gc'
UPDATE:However, as @plashnoted in a comment below, this flag will only work in debug builds.
更新:但是,正如@ plash在下面的评论中指出的那样,此标志仅适用于调试版本。
回答by Marcel Korpel
I see at least one (or two) flaws:
我看到至少一个(或两个)缺陷:
snd = new Audio(url);
has no varin front of it, so sndis assigned to the global scope. That's usually not what you want: it clutters the global name space and if another script (e.g., an extension) incidentally uses snd, things will be a mess.
var在它前面没有,所以snd分配给全局范围。这通常不是您想要的:它使全局名称空间snd混乱,如果另一个脚本(例如,扩展)偶然使用,事情就会变得一团糟。
And that's also why
这也是为什么
delete snd;
doesn't work: you can't delete global variables:
不起作用:您不能删除全局变量:
When declared variables and functions become properties of a Variable object — either Activation object (for Function code), or Global object (for Global code), these properties are created with DontDelete attribute.
当声明的变量和函数成为 Variable 对象的属性时——无论是 Activation 对象(对于函数代码)还是全局对象(对于全局代码),这些属性都是 使用 DontDelete 属性创建的。
So, use
所以,使用
var snd = new Audio(url);
instead. BTW, you can't force the JavaScript engine to do garbage collection.
反而。顺便说一句,您不能强制 JavaScript 引擎进行垃圾收集。
回答by user347594
Just deleting and setting it to null didn't work for me either, so I made a workaround.
只是删除并将其设置为 null 对我也不起作用,所以我做了一个解决方法。
I got it working for more than one sound at the same time. To release the instances, every sound needs to be an Object Tag. Dynamically, append every Object Tag (sound) to a Div. To release the instance, dynamically remove the Object Tag (sound) from the Div.
我让它同时为不止一种声音工作。要释放实例,每个声音都需要是一个对象标签。动态地,将每个对象标签(声音)附加到 Div。要释放实例,请从 Div 中动态删除对象标签(声音)。
I guessthis works because a browser typically implements each tag as some kind of object. So, when I delete a tag, the internal object gets deleted and releases any resources associated with it.
我想这是可行的,因为浏览器通常将每个标签实现为某种对象。因此,当我删除一个标签时,内部对象会被删除并释放与其关联的所有资源。
<!--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');
For complete object params go here.
有关完整的对象参数,请转到此处。
//To Stop an MP3 and release it instance.
$('#AUDIOIE' + id_event).empty().remove();

