一篇介绍Node垃圾回收机制的文章中,举了一段如下代码的示例来说明内存泄漏,望社区哪位朋友帮忙详细的解释一下啊!谢谢
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, 1)
你可以在命令行试下 new Array(1000000).join('*')
就知道了,资源只声明不释放再加上死循环,肯定内存泄漏
@fyibmsd 内存泄漏肯定是声明的资源没有释放。但这段代码的关键应该是 unused 这个 function 中引用了外部对象 originalThing 形成闭包,引起词汇作用域问题。如果注释掉 unused 这个 function,在 node 下跑好像是木有问题的,但是吧~我还是不能很明白的解释这个问题。
@AirccGit 你都自己回答自己了,还木有明白?通常闭包有几个好处,可以达到惰性求值的效果,还有个作用闭包作用域内的变量不会被gc回收,所以可以拿来模拟私有变量,或者希望变量常驻内存,或者避免全局变量污染,如果你看过之前node的require和module机制的话,应该还记得每一个node module就是一个个 function(){……return function(……)}() 这样的结构,真是利用了闭包的有点让模块常驻内存,你非要把这个优点当缺点用当然有问题了,比如 你新建一个a.js 里面放这段代码: module.exports=new Array(10000000).join(*) 然后你统计目录下新建一个问价b.js 写这么一段代码:var a=require(’./a6’); require(‘http’).createServer().listen(8888) 然后run起来,依然内存泄露,你的模块a文件永远常驻内存.不知我这么说你明白木有
同级目录,不是统计目录,打错了抱歉噢
@fantasticsoul Thanks! 本质上我是不太理解 作用闭包作用域内的变量不会被gc回收
, 如果 unused
对象不是 Function 而是一个普通对象的话,gc会回收掉 就不存在内存泄漏这个问题了。
难道未引用的闭包不会释放的吗