餐馆中的服务员—垃圾回收


垃圾制造者的产生,推动了垃圾处理者的出现,所以在我们现在的生活中,人们生产的垃圾都会通过相应的手段去处理掉,而不影响现代人的正常生活。程序来源于生活,所以程序世界也如同现代世界一样,也要产生垃圾。当然,也需要垃圾回收员来处理生产出来的垃圾.

垃圾

在程序世界中,不再被任何变量使用的对像,或者说不再被继续使用的变量就是垃圾。

function(){
  var a=0;//声明变量并赋值
  a++;//对变量进行操作
  //下面都没有对变量a进行操作,也就是没有使用变量a,那变量a就变成了垃圾.
  var b=0;
  b++;
}

可以把这个函数当作为一个餐馆,变量就相当于客人,坐在餐桌上吃饭的时候,就是在对变量进行操作,在占用着那个餐桌。但是当客人吃完离开后,产生的垃圾还是占用了那个桌子。服务员如果不来收拾,就会一直占用着那个桌子,一直占用着那个内存,也就成了程序中的垃圾。

垃圾回收

javascript中具有自动垃圾回收的机制,js的程序会找出那些不再被继续使用的变量,自动释放不再被任何变量使用的垃圾对象的内存空间。

function(){
  //局部变量在函数结束后,便会自动被收回内存
  var a=0;
  a++;
}

还是餐馆中,客人吃完饭后产生的垃圾,还是占用了那个桌子,表现在程序中,就还在占用着那块内存。那此时服务员清理垃圾以供接下来的顾客使用,便是垃圾回收。

垃圾的危害

内存中空间都是有限的,内存占用越多,自然程序运行的越慢,当内存满了的时候,程序就无法运行,就像餐馆,如果没有服务员,每个顾客用完餐滞留的垃圾无法清理,那餐馆可供顾客进餐的餐桌就会越来越少,等到餐桌都被垃圾占满,那这个餐馆也就无法营业了。

垃圾回收器

js引擎中,专门监控,并释放垃圾的小程序。它有几个特点

  • 伴随主程序在后台并行执行

  • 会记录每个对象被几个变量使用着

  • 只要发现一个对象不再被任何变量使用,就释放该对象所占内存

这些特点也是和现实中餐馆的服务员一样

  • 服务员会在餐馆营业时间一直工作(伴随主程序),他不会打扰每位顾客的进餐(在后台)。

  • 当有顾客进来餐馆的时候,他会记录顾客的桌位,并且记录此桌位上顾客的个数

  • 只要发现餐桌上有垃圾并且没有人在进餐了,他就会过去清理掉这些垃圾

策略

具体到浏览器中,垃圾回收有两个策略,这两个策略书上解释的很详细,网上解释的也比较多,小白我就不在此详细解释了,简单的说一下就好.

标记清除

当变量进入环境的时候就为变量标记为”进入环境”,当变量离开环境的时候,会被标上”离开环境”。

垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记。然后,它会去掉环境中的变量以及被环境中的变量引用的标记。而在此之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。最后。垃圾收集器完成内存清除工作,销毁那些带标记的值,并回收他们所占用的内存空间。

引用计数

另一种不太常见的垃圾回收策略是引用计数。引用计数的含义是跟踪记录每个值被引用的次数。当声明了一个变量并将一个引用类型赋值给该变量时,则这个值的引用次数就是1。相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值的引用次数就减1。当这个引用次数变成0时,则说明没有办法再访问这个值了,因而就可以将其所占的内存空间给收回来。这样,垃圾收集器下次再运行时,它就会释放那些引用次数为0的值所占的内存。

当然这个存在一些问题,这个就不过多说了。具体可以翻阅《js高级程序设计(第三版)》的垃圾收集处。

建议

虽然js有主动垃圾回收的机制,但是程序还是需要一定的判断,而且是有时间间隔的。服务员不可能在你吃饭的时候一直盯着你问你,“你啥时候吃完啊,好了没?”,所以还是建议,只要一个变量不再使用的时候,要主动为其赋值为null。 就相当于,在餐馆吃饭,少点的垃圾,就自己收拾了呗。反正我一般都不收拾 (滑稽)

原文在博客里面,有兴趣的大佬可以去支持一下小白的博客


发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>