如何关闭内存GCed?

时间:2018-04-26 00:09:54

标签: javascript dom memory-management

所有

我是javascript管理的新手,当我尝试理解GC如何处理闭包时,我运行了一个例子:

function addN(n){
    var title = "ADD "+n;
    return function adder(who){
        return who+n;
    }
}
var add3 = addN(3);
var result = add3(10);

我想知道addN完成为add3构建关闭后, title仍然留在内存中,或者它只是n吗?

另一个例子是:

var globaltable = []
function addNarray(narray){
    // narray is an string array
    var titles = narray.slice(0);
    globaltable = globaltable.concat(titles);
    return function adder(who){
        return narray.join(" - ");
    }
}

在此示例中,title获得GCed 吗?

我也想知道如果那个叙事是一个像{id:0, name:"idname"}这样的对象数组,那么答案是否相同?

如果有人知道答案,请分享一个想法,并且一个chrome devtool方式证明将非常感激,或者从内存使用角度解释一下

由于

1 个答案:

答案 0 :(得分:4)

您可以使用console.dir(add3);查看闭包的构造。展开[[Scopes]]属性,然后展开0: Closure对象,您将只看到:

n: 3

闭包不会将title的值保存在任何地方。

在第二个示例中,titles变量仍然是垃圾回收。当你这样做时:

var titles = narray.slice(0);
globaltable = globaltable.concat(titles);

发生以下情况:

  1. narray的副本由slice()创建,并存储在本地变量titles中。
  2. 包含globaltable内容后跟titles内容的新数组。
  3. 此新数组存储在globaltable
  4. 此时globaltable的旧值变为垃圾。当addNarray()返回时,titles的值变为垃圾,因为adder()中的闭包没有任何对它的引用。

    titles中的字符串不会变成垃圾,因为它们仍在globalarray中引用。并且narray不会变成垃圾,因为它是adder闭包中的引用。

    基本上,闭包应保持对返回函数中某处提到的变量的引用。外部范围中的其他变量不需要保存。

    垃圾收集的基本原理很简单:如果无法访问一段数据,可以将其收集为垃圾。实施中有时会出现错误,但作为一般规则,您可以认为这是真的。