jiangmugit / js_desc

随便记录点东西
0 stars 0 forks source link

js垃圾回收机制(包含闭包解释) #3

Open jiangmugit opened 5 years ago

jiangmugit commented 5 years ago

变量是存在于内存中的,但是内存是有限的,在js运行过程中,阶段性的去寻找没用变量,并回收释放内存的这一过程叫垃圾回收

1.标记清除法(最主流的浏览器垃圾回收机制) 第一种,在函数创建变量的时候,该变量先有一个进入环境的标记,当函数执行完,将变量标记为离开环境,那么执行完之后这个变量将不再可用,这个时候这个变量有个可能在一个待清除的列表中或者什么鬼的地方,总之我查了一下,有一种说法是说当内存被耗尽的时候这些内存中的垃圾就会被清除,这就意味着在实际的程序运行过程中,并不是说我一个函数执行完就立马去清除它创建的变量。这个时候杠精们是不是想到了闭包?? 是的是这样的,据说垃圾回收的时候会有一个根递归的方式。就是从window对象开始往下遍历递归, 例如

function a () {
   var b = 0
   return function () {
      console.log(b++)
   }
}
var c = a()

这是个很常见的闭包嘛 那么闭包产生的原理是什么呢。

我们来读一下这段代码 定义一个变量a它是一个函数 这个方法里面定义个局部变量b,返回一个函数 打印b变量的累加 定义一个c变量,赋值a函数执行完后的返回值。也就是c也是个函数,打印b++

根据刚刚说的垃圾回收机制的道理,在a函数执行完了之后局部变量b会被标记并等待清除,此时b不可再被引用,实际上是这样的,当我在a执行到var b = 0 的时候,在内存开辟了一块地方来存这个 0 当a执行完之后,b本来是要被标记成要被回收的,但是呢,突然发现,咦,这玩意我返回的那个家伙它也要用到,哦吼,凭着一股甩锅精神,我现在执行完了我不管了,这个存着0的地址和我没关系了,要找你去找我返回那个人去,现在这个地址归他引用,要不要回收你别问我 去问他,然后就去问了这个变量c,这个东西我能不能回收?c的答案是,只要我还是这个函数你就别动它,我不知道什么时候被别人调用,当我被调用的时候我就要用到它,所以这个东西就被一直存放在了内存中。那什么时候可以去回收这个内存中的变量呢?刚刚c告诉我说它不知道什么时候会被调用,一被调用就要用到,让我别动这个内存中的东西,那我现在知道你c不会再被调用了,我直接把你c给干掉把,c=null;那你现在没什么说的了,这个内存中存在的变量我要回收并释放内存了