我想触发JavaScript垃圾回收。这是否可能?为什么我想要或不想要这样做?
我想触发JavaScript垃圾回收。这是否可能?为什么我想要或不想要这样做?
我出去小旅行了一下,想要找到你的一个问题的答案:这是可能的吗?
全城的人都在说删除引用就可以解决问题。有些人说擦除对象是额外的保证(example)。所以我写了一个脚本,尝试了书中的每个技巧,惊讶地发现在Chrome(22.0.1229.79)和IE(9.0.8112.16421)中,垃圾回收甚至似乎不起作用。Firefox(15.0.1)没有遇到任何主要缺点,除了一个(请参见下面的4f案例)。
在伪代码中,测试大致如下。
创建一个容器,一个数组,用于存储某种类型的对象。我们将在此称这个容器为 Bertil
。
每个元素都是一个对象,在 Bertil 中作为属性声明自己的数组容器。这个数组将保存很多字节。我们将 Bertil 的任何一个元素称为“对象”,Joshua
。每个 Joshua 的字节数组将被称为 Smith
。
这里有一个思维导图供您参考:
Bertil
[对象数组] -> Joshua
[对象] -> Smith
[字节数组] -> 未命名 [字节]。
当我们把可用内存搞乱时,请等待一两秒钟,然后执行以下任意一种“销毁算法”:
4a. 在主对象容器 Bertil 上抛出一个删除操作数。
4b. 在该容器中的每个对象上抛出一个删除操作数,杀死每个活着的 Joshua。
4c. 在每个字节数组中抛出一个删除操作数,即 Smiths。
4d. 将 NULL 分配给每个 Joshua。
4e. 将 UNDEFINED 分配给每个 Joshua。
4f. 手动删除 Joshua 持有的每个字节。
4g. 以工作顺序执行所有上述操作。
在所有浏览器的GC未能启动的情况下,等待至少10分钟并不能解决问题。重新加载整个页面会导致内存占用量翻倍。
我的结论是我在代码中一定犯了严重的错误,或者您的问题的答案是:不,我们不能触发GC。每当我们试图这样做时,我们将受到严厉的惩罚,并且应该把头埋进沙子里。请鼓励您自己前进,尝试这些测试用例。查看代码中的注释以获取详细信息。此外,下载页面并重新编写脚本,看看是否可以以更适当的方式触发GC。我肯定失败了,我无法相信Chrome和IE没有一个有效的垃圾回收器。http://martinandersson.com/dev/gc_test/?case=1
http://martinandersson.com/dev/gc_test/?case=2
http://martinandersson.com/dev/gc_test/?case=3
http://martinandersson.com/dev/gc_test/?case=4
http://martinandersson.com/dev/gc_test/?case=5
delete
应该尽量避免,除非绝对需要。为什么?因为它会破坏该对象的JS引擎优化,至少在V8中是如此...我不确定其他引擎是否也是如此。您可以通过使用分析器实时查看此情况。如果您在键上调用delete
,则会在分析器中看到该对象现在被标记为“取消优化”。好文章:https://github.com/P0lip/v8-deoptimize-reasons - th317erd您可以手动触发IE和Opera中的JavaScript垃圾回收器,但不建议这样做,最好完全不使用它。我提供更多的命令只是为了信息目的。
Internet Explorer:
window.CollectGarbage()
Opera 7+:
window.opera.collect()
这个答案提供了以下垃圾回收请求代码,适用于基于Gecko的浏览器:
window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils)
.garbageCollect();
我看到了这个问题,决定分享一下我最近的发现。
我研究了在Chrome中正确处理WeakMap的方法,实际上看起来还不错:
1)var wm = new WeakMap()
2)var d = document.createElement('div')
3)wm.set(d, {})
此时WeakMap保存了该条目,因为d仍然引用该元素
4)d = null
此时没有任何东西引用该元素和它的弱引用对象,几分钟后该条目消失并被垃圾回收。
当我将元素添加到DOM中并执行相同的操作时,它没有被回收,这是正确的,因为它已从DOM中删除,并且仍在等待被回收 :)
是的,您可以通过重新加载页面来触发垃圾回收。
您可能希望考虑使用工厂模式来帮助重复使用对象,这将大大减少创建的对象数量。特别是,如果您不断地创建相同的对象。
如果您需要了解工厂模式,请获取Ross Harmes和Dustin Diaz撰写、APress出版的《Pro Javascript Design Patterns》一书。