什么是JavaScript的垃圾回收?

17 浏览
0 Comments

什么是JavaScript的垃圾回收?

JavaScript垃圾回收是什么?为了编写更好的代码,Web程序员理解JavaScript垃圾回收的重要性是什么?

admin 更改状态以发布 2023年5月19日
0
0 Comments

当涉及到DOM对象时,请注意循环引用:

JavaScript中的内存泄漏模式

请记住,只有在没有对象的活动引用时,内存才能被回收。这是使用闭包和事件处理程序的常见陷阱,因为某些JS引擎不会检查哪些变量实际上在内部函数中被引用,它只会保留封闭函数的全部局部变量。

这里是一个简单的例子:

function init() {
    var bigString = new Array(1000).join('xxx');
    var foo = document.getElementById('foo');
    foo.onclick = function() {
        // this might create a closure over `bigString`,
        // even if `bigString` isn't referenced anywhere!
    };
}

naiveJS实现只要事件处理程序还存在,就无法收集bigString。有几种解决这个问题的方法,例如在init()的结尾设置bigString = nulldelete对于局部变量和函数参数不起作用:delete从对象中删除属性,而变量对象是不可访问的 - 即使在严格模式下的ES5中,如果您尝试删除局部变量也会抛出ReferenceError!)。

我建议尽可能避免不必要的闭包,如果您关心内存消耗。

0
0 Comments

Eric Lippert曾经写过一篇关于这个主题的详细博客文章(同时将其与VBScript进行了比较)。更准确地说,他写了关于Microsoft自己实现的ECMAScript(名为JScript)的文章,虽然非常类似于JavaScript。我想你可以认为绝大多数行为对于Internet Explorer的JavaScript引擎都是相同的。当然,具体实现会因浏览器而异,但我认为你可以采用许多常见的原则并将其应用于其他浏览器。

从那个页面中引用:

JScript使用非代际化的标记-清除垃圾回收器。它的工作方式如下:

1. 每个“在范围内”的变量被称为“清道夫”。清道夫可以引用数字、对象、字符串等。我们维护一个清单,当变量进入范围时,将它们移到清单上,当它们出了范围时,将它们从清单中删除。

2. 每隔一段时间,垃圾收集器会运行。首先,它在GC跟踪的所有内存上放置一个“标记”,包括每个对象、变量、字符串等(JScript在内部使用VARIANT数据结构,并且该结构中有足够多的未使用位,因此我们只需将其中一个位设置为标记)。

3. 其次,它清除了清道夫和其传递闭包的引用上的标记。因此,如果一个清道夫对象引用了一个非清道夫对象,那么我们清除了非清道夫对象和它引用的所有内容上的标记(我在这里使用“闭包”一词的意思与我的早期文章不同)。

4. 在此点上,我们知道仍然标记的所有内存是已分配的内存,它们无法从任何“在范围内”的变量通过任何路径被访问到。所有这些对象都被指示自我销毁,这会摧毁任何循环引用。

垃圾回收的主要目的是允许程序员不用担心他们创建和使用的对象的内存管理,尽管肯定有时候不可避免 - 至少拥有如何垃圾收集工作的大概了解总是有益的。

历史注解:此回答的早期版本有一个错误引用到delete运算符。在JavaScript中,delete运算符从一个对象中删除一个属性,与C / C ++中的delete完全不同。

0