萌新,请问下,为什么下面这段代码,会导致内存堆积
RT.
var o = null
function replaceObject() {
let n = o
o = {
arr: new Array(100000)
}
o.fn = function() {
console.log(n)
}
}
var num = 100 // 加大 num 不能释放的内存越多
for (let i = 0; i < num; i++) {
replaceObject()
}
下面这种写法,就不会
var o = null
var z = null
function replaceObject() {
let n = o
o = {
arr: new Array(100000)
}
z = {
fn() {
console.log(n)
}
}
}
var num = 100 // 加大 num 不会堆积内存
for (let i = 0; i < num; i++) {
replaceObject()
}
8 回复
node - v6.10.2 node - v8.7.0 以上效果一样
顶下,求解中。
区别在于,一个闭包了原先的自己,一个闭包了原先的别人
盲区,结果论是如此。就结果来说,一个能从标记清除的根里找回内存引用,一个不能找到,所以前者堆积,后者被释放
上面的情况
// 第一次replaceObject
let n = o // 此时是null
o = { // 第一个o,暂且称为o1
arr: new Array(100000)
}
o.fn = function() {
console.log(n) // 这个n是null,没问题
}
// 第二次replaceObject
let n = o // 此时是o1
o = { // 第二个o,暂且称为o2
arr: new Array(100000)
}
o.fn = function() {
console.log(n) // 这个n是o1,显然只要o2存在,则o1不应被回收
}
// ...接下来继续
// o3将引用o2,导致o2无法回收,o4引用o3......
下面的情况自己应该就能想明白了吧
@dislido 从引用论解释的话,那这种情况也说的通了。
var o = null
function replaceObject() {
let n = o
function bn() {
console.log(n)
}
o = {
arr: new Array(100000),
fn() {
// 与 bn 共享作用域,bn 引用了老的 n,同上引用论解释
console.log('')
}
}
}
var num = 100 // 加大 num 不能释放的内存越多
for (let i = 0; i < num; i++) {
replaceObject()
}
因为两个函数在同一个作用域里,一个产生全局闭包,另一个无引用,但是他们的作用域共享,导致一样的结果
meteor.js 发现的问题的解释了。
第一段代码循环引用了,@dislido 讲的很好 第二段代码,变量 z,每次都会清空,就不会内存泄漏。