我可以触发JavaScript的垃圾收集吗?

Abh*_*nav 52 javascript garbage-collection

我想触发JavaScript垃圾回收.可能吗?我为什么要或不想这样做?

Mar*_*son 49

我出去了一个小小的旅程,寻求你的一个问题的答案:有可能吗?

全城各地的人都说删除参考文献就可以了.有人说擦拭物体是一个额外的保证(例如).所以我写了一个脚本,将尝试书中的每一个技巧,我很惊讶地看到在Chrome(22.0.1229.79)和IE(9.0.8112.16421),垃圾收集似乎甚至没有工作.Firefox(15.0.1)管理没有任何重大缺点(见下面的案例4f).

在伪代码中,测试就是这样的.

  1. 创建一个容器,一个数组,它将保存某种对象.我们Bertil在这里称这个容器.

  2. 其中的每一个对象,作为Bertil中的一个元素,都应该将自己的数组容器声明为属性.这个数组将包含很多字节.我们会打电话给贝蒂尔的元素,任何一个对象,Joshua.将调用每个Joshua的字节数组Smith.

    这是一个思维导图供您依靠:

    Bertil[对象数组] - > Joshua[对象] - > Smith[字节数组] - >未命名[字节].

  3. 当我们从可用内存中弄出一团糟时,请暂停一两秒,然后执行以下任何一种"破坏算法":

    4A.在主对象容器Bertil上抛出一个删除操作数.

    4B.在该容器中的每个对象上抛出一个删除操作数,杀死每一个活着的Joshua.

    4C.在每个字节数组(Smiths)上抛出一个删除操作数.

    4D.为每个Joshua分配NULL.

    4E.将UNDEFINED分配给每一个约书亚.

    4F.手动删除Joshua持有的每个字节.

    4克.在工作顺序中完成上述所有操作.

所以发生了什么事?在案例4a4b中,没有浏览器的垃圾收集器(GC)启动.在4c到4e的情况下,Firefox确实启动并显示了一些概念证明.记忆在一分钟之内就被收回了.对于用作测试配置的某些变量的当前硬编码默认值,情况4f4e导致Chrome挂起,因此我无法得出任何结论.您可以使用自己的变量自由进行测试,链接将很快发布.IE幸存下来的案例4f和4e,但他的GC像往常一样死了.出乎意料的是,Firefox幸免于难,但未通过4f.Firefox幸存并传递了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

http://martinandersson.com/dev/gc_test/?case=6

http://martinandersson.com/dev/gc_test/?case=7

  • 我还注意到在 V8 引擎 (Chrome) 中删除大量对象是一个坏主意。它只是非常慢,分配给 null 的速度要快得多。 (2认同)
  • 你说:"删除大量的物品".可能很高兴知道你不能删除JS中的对象(也不是函数或变量),只能删除对象属性和数组元素.在我们完成em之后,为每个对象引用分配null(或未定义的?)应该是我们需要做的.理论上.但正如我的小研究证明我在Chrome和IE中启动GC时完全失败了.基本上,应该很难用自己的垃圾收集器在托管代码中实现内存泄漏,对我来说,情况正好相反. (2认同)
  • +1,可能是我在SO上读过的最好的答案。娱乐性(但不是太过分)地写在现场。我正在构建真正的动态数据管理-可能会将浏览器用作Google Spreadsheets等的数据桥。因此,“您有太多数据”也是我的问题... (2认同)
  • @MartinAndersson我去了你的测试.然后发现(也在下面的答案中提到),IE尊重显式调用"CollectGarbage()"(我只是通过测试它将它添加到你的案例2模式 - 没有彻底测试).虽然它是"不推荐",但它可以释放内存,而等待却没有释放任何东西...... (2认同)

mas*_*bot 7

您可以在IE和Opera中手动触发JavaScript垃圾收集器,但不建议这样做,所以最好不要使用它.我更多地提供命令仅供参考.

IE浏览器:

window.CollectGarbage()
Run Code Online (Sandbox Code Playgroud)

Opera 7+:

window.opera.collect()
Run Code Online (Sandbox Code Playgroud)


jfr*_*d00 6

垃圾收集自动运行.如何以及何时运行并实际释放未引用的对象完全是特定于实现的.

如果你想要释放一些东西,你只需要从你的javascript清除对它的任何引用.然后垃圾收集器将释放它.

据我所知,没有办法手动触发垃圾回收.

如果你解释为什么你甚至认为你需要这样做或想要这样做并向我们展示相关的代码,我们可以帮助解释你的替代品是什么.

  • 我已经回答过你在没有看到你的代码的情况下可以做些什么.你不能自己调用​​垃圾收集器.如果清除对这些大数据的所有引用并允许一些自由循环到JS引擎,垃圾收集器将为您释放它.我只能通过查看您的特定代码来建议如何做到这一点. (4认同)
  • @Abhinav - 清除浏览器内存的另一种方法是重新加载页面而不是仅使用ajax并保持在同一页面上 - 尽管如果您的代码结构正确以释放对数据的引用它不再需要. (3认同)
  • 嗨,实际上在我的应用程序中,每20秒就有大量数据通过ajax调用.由于重型数据浏览器在几分钟后崩溃.所以我想清除浏览器的内存以避免浏览器的失败 (2认同)