我可以触发 JavaScript 的垃圾回收吗?
我想触发 JavaScript 垃圾回收.是否可以?我为什么要或不想这样做?
I want to trigger JavaScript garbage collection. Is it possible? Why would I want to, or not want to, do this?
推荐答案
我踏上了一小段旅程,想要回答你的一个问题:有可能吗?
I went out on a small journey to seek an answer to one of your questions: Is it possible?
全城的人都在说删除引用就行了.有人说擦除对象是额外的保证(示例).所以我写了一个脚本来尝试书中的每一个技巧,我惊讶地发现在 Chrome (22.0.1229.79) 和 IE (9.0.8112.16421) 中,垃圾收集似乎不起作用.Firefox (15.0.1) 的管理没有任何重大缺陷,除了一个(参见下面的案例 4f).
People all over town are saying that deleting the references will do the trick. Some people say that wiping the object is an extra guarantee (example). So I wrote a script that will try every trick in the book, and I was astonished to see that in Chrome (22.0.1229.79) and IE (9.0.8112.16421), garbage collection doesn't even seem to work. Firefox (15.0.1) managed without any major drawbacks apart from one (see case 4f down below).
在伪代码中,测试是这样的.
创建一个容器,一个数组,用于保存某种对象.我们将在此处将此容器称为
Bertil
.
其中的每个对象,作为 Bertil 中的一个元素,都应将其自己的数组容器声明为属性.该数组将保存大量字节.我们将调用 Bertil 的任何元素,对象,Joshua
.每个 Joshua 的字节数组将被称为 Smith
.
Each and every object therein, as an element in Bertil, shall have his own array-container declared as a property. This array will hold a whole lot of bytes. We'll call any one of Bertil's elements, the object, Joshua
. Each Joshua's byte array will be called Smith
.
这里有一张思维导图供你参考:
Here's a mind map for you to lean back on:
Bertil
[对象数组] -> Joshua
[对象] -> Smith
[字节数组] -> 未命名 [字节].
Bertil
[Array of objects] -> Joshua
[Object] -> Smith
[Array of bytes] -> Unnamed [Bytes].
当我们把可用内存弄得一团糟时,停留一两秒,然后执行以下任一破坏算法":
When we've made a mess out of our available memory, hang around for a sec or two and then execute any one of the following "destruction algorithms":
4a.在主对象容器 Bertil 上抛出一个删除操作数.
4a. Throw a delete operand on the main object container, Bertil.
4b.对该容器中的每个对象都抛出一个删除操作数,杀死所有活着的 Joshua.
4b. Throw a delete operand on each and every object in that container, kill every Joshua alive.
4c.对每个字节数组(Smiths)抛出一个删除操作数.
4c. Throw a delete operand on each and every array of bytes, the Smiths.
4d.将 NULL 分配给每个 Joshua.
4d. Assign NULL to every Joshua.
4e.将 UNDEFINED 分配给每个 Joshua.
4e. Assign UNDEFINED to every Joshua.
4f.手动删除任何 Joshua 保存的每个字节.
4f. Manually delete each and every byte that any Joshua holds.
4g.按正常顺序执行上述所有操作.
4g. Do all of the above in a working order.
那么发生了什么?在 4a 和 4b 的情况下,没有浏览器的垃圾收集器 (GC) 启动.在 4c 的情况下到 4e,Firefox 确实启动并展示了一些概念证明.记忆在一分钟内很快被回收.使用当前硬编码的一些变量作为测试配置的默认值,案例 4f 和 4e 导致 Chrome 挂起,所以我不能在那里得出任何结论.您可以自由地使用自己的变量进行自己的测试,链接将很快发布.IE 在 4f 和 4e 病例中幸存下来,但他的 GC 像往常一样死了.出乎意料的是,Firefox 幸存下来但没有通过 4f.Firefox 幸存下来并通过了 4g.
So what happened? In case 4a and 4b, no browser's garbage collector (GC) kicked in. In case 4c to 4e, Firefox did kick in and displayed some proof of concept. Memory was reclaimed shortly within the minute. With current hardcoded default values on some of the variables used as test configuration, case 4f and 4e caused Chrome to hang, so I can't draw any conclusions there. You are free to do your own testing with your own variables, links will be posted soon. IE survived case 4f and 4e but his GC was dead as usual. Unexpectedly, Firefox survived but didn't pass 4f. Firefox survived and passed 4g.
在浏览器的 GC 未能启动的所有情况下,等待至少 10 分钟并不能解决问题.并且重新加载整个页面会导致内存占用翻倍.
In all of the cases when a browser's GC failed to kick in, waiting around for at least 10 minutes didn't solve the problem. And reloading the entire page caused the memory footprint to double.
我的结论是我一定在代码中犯了一个可怕的错误,或者你的问题的答案是:不,我们不能触发 GC.每当我们试图这样做时,我们都会受到严厉的惩罚,我们应该把头埋在沙子里.请我鼓励你继续,自己尝试这些测试用例.看看代码中对细节的评论.另外,下载页面并重写脚本,看看是否可以以更合适的方式触发 GC.我确实失败了,我一辈子都不能相信 Chrome 和 IE 没有工作的垃圾收集器.
My conclusion is that I must have made a horrible error in the code or the answer to your question is: No we can't trigger the GC. Whenever we try to do so we will be punished severely and we should stick our heads in the sand. Please I encourage you to go ahead, try these test cases on your own. Have a look in the code were comment on the details. Also, download the page and rewrite the script and see if you can trigger the GC in a more proper way. I sure failed and I can't for the life of me believe that Chrome and IE doesn't have a working garbage collector.
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
http://martinandersson.com/dev/gc_test/?case=6
http://martinandersson.com/dev/gc_test/?case=7
相关文章