v8的垃圾回收机制

v8是Google推出的JS引擎,他不仅提升了Chrome的性能,也为node提供了很好的支持,这次就来大致了解一下它其中的垃圾回收回收机制。

  

一、内存限制

      v8限制用户只能使用部分内存(当然,这个限制大小也可以用户自己设置,默认64位约为1.4GB,32位约为0.7GB)

  原因:以1.5GB的垃圾回收堆内存为例,v8做一次小的垃圾回收需要50ms以上,做一次非增量式的垃圾回收甚至要1秒以上。

               在这样子时间开销下,性能和响应能力直线下降。

二、分代式垃圾回收机制

     出现原因:在自动垃圾回收的演变过程中,没有固定一种回收算法能胜任所有场景,采取分代式,可以对不同的代进行不能的处理,以提高效率。

        堆上:   

        新生代空间:存放存活时间短的对象

        老生代空间:存放存活时间长的对象

  1、新生代算法:   主要采用Scavenge算法

   

          过程:

            先在新生代区,将堆内存对半分,一半处于使用(即From区),另一半处于闲置(即To区),平时在From区进行操作。到了要回收的时候,检测From区的对象,存活的对象复制到To     

                区,然后From区被释放了,之后对To区和From区调换名字,继续重复之前操作

      缺点:只能使用一半空间,耗空间

          优点:只需要复制少部分存活的对象,因为生命周期短的对象中存活的比较少,节省时间

  注意:当一个对象被复制多次依然存活,则被晋升到老生代,进行管理

    (晋升条件:经历过Scavenge算法或To区使用超出25%)

   2、老生代算法:   标记清除算法 搭配 标记整理算法算法

  过程:

    标记清除算法,先将存活的对象进行标记,清除时只清除没有标记的(老生代中都是生命周期长的对象,刚好死亡的对象少),不过此时会出现内存不连续的情况。但是,如果此时需要放一个大对象,则放不下,从而导致再次引起回收。然而这次回收是不必要的。

                                                                               

            标记整理算法,先将死亡的对象进行标记,然后将存活得对象往一段移动,移动完成后,清理掉边界外的内存。

                                                                                            

     总结:

      

                   可以看出标记整理相对较慢,V8主要还是使用标记清除,只有在新生代发生晋升,导致老生代分配不出足够空间时,采用标记整理

  

     3、增量标记

       上述三种方式局限:都需要将应用暂停下来,等待执行回收,回收执行完毕才继续应用逻辑。特别是v8老生代,因为配置较大,存活的对象多,导致标记、清除、整理带来的停顿更加严重。

      增量标记可以将上述步骤拆成更细的“粒度”,让回收中的标记阶段和应用逻辑交替进行,v8引入这个方式后最大停顿减少到原本1/6

         

           4、延迟清除、增量式整理

           将清除阶段和整理阶段也进行了“增量式改造”

   

         

备注:摘取《深入浅出nodejs》 

猜你喜欢

转载自www.cnblogs.com/qianbin/p/10425213.html
今日推荐