Javascript 为什么这个js函数会导致内存泄漏?

Javascript 为什么这个js函数会导致内存泄漏?,javascript,memory-leaks,garbage-collection,Javascript,Memory Leaks,Garbage Collection,我不明白这段代码是如何导致内存泄漏的 var theThing = null; var replaceThing = function () { var originalThing = theThing; var unused = function () { if (originalThing) console.log("hi"); }; theThing = { longStr: new Array(100

我不明白这段代码是如何导致内存泄漏的

var theThing = null;
var replaceThing = function () {
    var originalThing = theThing;
    var unused = function () {
        if (originalThing)
            console.log("hi");
    };
    theThing = {
        longStr: new Array(1000000).join('*'),
        someMethod: function () {
            console.log(someMessage);
        }
    };
};
setInterval(replaceThing, 1000);
如果我在函数
replaceThing
的末尾将
originalThing
设置为null,则一切都会正常。但是我在这里没有看到一个引用循环,我不知道为什么不能释放这些闭包

v8 GC不使用标记扫描吗?如果我把这些代码放到生活中,内存泄漏仍然存在。但是根上下文如何到达这些变量和函数呢? 我使用chrome来测试这些代码。现在我对GC如何在闭包上工作感到困惑。

请参见

因为内部函数持有对外部函数变量的引用,所以范围对象…不会被垃圾收集


在第一次调用中,
originalThing
被赋值为null后,
theThing
成为对新对象的引用,第二次和后续调用
originalThing
将引用赋值给对象,然后再次
theThing
成为对新对象的引用,但是
originalThing
将链接到上一个对象

你是说找不到
someMessage
吗?但我尝试将其替换为字符串
'someMessage'
。内存泄漏仍然存在。谢谢,我明白了,但我仍然有一些问题。首先,我理解了深层嵌套上下文是如何产生的,但是为什么这个上下文不能被释放,因为在第一个上下文中,
originalThing
等于null,如果
theThing
不是全局的,在我调用
replaceThing
之后,
theThing
将不再被使用,它应该用
someMethod
触发。第二,当我删除
未使用的
时,泄漏似乎消失了。我找到了一个很好的资源(向下滚动到闭包):我看到了这句话,但我认为这是清单4的结论。在清单4中,内部函数已返回。
x
保存内部函数的引用,而内部函数保存外部函数的
a
,因此,当外部函数完成时,作用域对象仍然存在于内存中。但是
x('inner x')
之后发生的事情,如果
x
不是全局的,那么所有这些都是最后无法访问的。是的,但是为什么不能激发这些变量。如果GC使用标记扫描,所有这些都无法访问,因为对对象的一个引用仍然存在,但是如果保存对对象1的引用的对象不再需要呢?假设,obj1,obj2,下一个保存前一个,obj2由于obj1而无法激发,但是如果obj1也不需要,那么所有这些都应该激发。第一个
originalThing
为空,下一个保留前一个的引用,但当最后一个不再需要时,为什么不解雇它们。我误解了你的意思吗?好吧,我们来点吧。我们在
theThing
外部声明了变量,然后在
replaceThing
内部创建了一个函数,并创建了
originalThing
到外部
theThing
的链接。然后我们创建一个
unused
,其中
…if(originalThing).
=>对'theThing'的引用进一步更改
theThing
链接到一个新对象,但仍保留在前一个对象的'unused'链接中
theThing
,虽然在完成
replaceThing
GC后,我们将丢失上下文以及对象,但未清理
unused