X

作用域,闭包和内存泄漏

2022/7/26

这篇文章源于贴吧一个奇怪的内存泄漏问题

dece2d9b033b5bb50b73542573d3d539b400bc44.jpg

你会发现内存一直在升高

Screenshot 2022-07-19 174003.png

所以是内存泄露了

但是为什么会泄露呢

我们先看一个简单例子:

carbon (3).png

我们可以看到:

Screenshot 2022-07-20 125400.png

array在内存中一直占用没有释放

明明a是没有被使用

这里就涉及到一个概念 作用域和闭包

闭包准确来说就是在一个作用域内使用了另外一个作用域的变量

它的效果就是

1.将该变量添加到该变量所在的作用域

2.将该变量所在的作用域添加到自己的作用域链

所以一个作用域内 变量没使用是不会添加到作用域的

但闭包会让其变为变量对应作用域的成员

维持一个作用域的存在 就需要对应作用域成员存在引用关系

上图中 b 赋值了一个function

这一步很关键 function 会带着它的作用域

而此时它和未使用的方法_()作用域一样 都是带有数组 a 即同一个作用域内方法是会共享作用域 这个共享包括了作用域成员

因为b在外部var上 对应的是global上的b 所以这个引用会持续存在

所以b的作用域不会回收 对应成员也无法释放

那么要怎么解决呢?

很简单 移除b在全局对该作用域的引用即可

carbon (2).pngScreenshot 2022-07-20 125544.png

我们可以看到 内存里array已经没有占用了

回到最初的问题 我们整理一下代码

carbon.png

这段代码会内存泄露的根源是形成了作用域的嵌套

每一个周期都会外面套一层 即新作用域的成员对旧作用域的引用

从而一直无法释放

Commit