0%

闭包中的内存泄漏

闭包的定义:A closure is the combination of a function and the lexical environment within which that function was declared.(函数声明时函数内部变量有访问当前作用域链上变量的能力,哪怕变量被函数return出去以后。)

闭包具体场景:函数嵌套函数时,内层函数引用了外层函数作用域下的变量,并且内层函数被全局环境下的变量引用,就形成了闭包。

浏览器垃圾回收机制要点:

  • 从根对象开始寻找,只要能顺着引用找到的,都不能被回收。顺着引用找不到的对象被视为垃圾,在下一个垃圾回收节点被回收。
  • 变量显示引用次数如果标记为0也会被回收。

内存泄漏定义:通俗的讲也就是当某个对象我们不再需要,但是仍在长时间在内存中。

内存泄漏案例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var t = null;
var replaceThing = function() {
var o = t
var unused = function() {
if (o)
console.log("hi")
}
t = {
longStr: new Array(1000000).join('*'),
someMethod: function() {
console.log("this is a test")
}
}
}
setInterval(replaceThing, 1)

在replaceThing执行返回变量t以后,全局变量t有对replaceThing函数内变量访问的权利,这也是说内存保存着对o访问权利(注意此次o的引用次数因为在unsed有引用不为0),而o变量保存着上次执行的t,依次索引造成严重内存泄漏。下图是replaceThing执行三次后的情况:
内存泄漏
这里在函数最后可以将o=null解决内存泄漏,也可以将unsed去掉解决内存泄漏。