V8引擎垃圾回收算法

302 阅读2分钟

v8引擎是现在比较流行的javascript引擎,chrome和node中使用的都是v8引擎。

v8引擎内存限制原因

现在64位操作系统v8的最大内存为14GB,之所以v8对js使用内存有限制,有以下几点原因:

  • v8设计之初是针对于浏览器的使用场景,没必要将内存设置过高
  • js是单线程执行,垃圾回收的过程回阻碍主线程的执行,内存过大,执行消耗时间会比较长
  • 垃圾回收本身的消耗时间也比较大。

V8垃圾回收算法

v8将堆内存分为新生代和老生代,当然也有其他的分区,但是涉及到垃圾回收的主要是这两个部分。 新生代内存是由两个semispace(半空间)组成,其中处于激活状态的区域我们称之为from区,未激活区域我们称之为 to区,采用Scavenges算法。
新生代Scavenges算法:

1,遍历所有from区的对象,发现仍处于活跃状态的对象将其复制到to2,清除from内存中的对象
3fromto区进行呼唤,之前的to区变为from区,from区变为to

分配的新对象都分配在from区。

新生代晋升到老生代:
有两种情况

在新生代进行垃圾回收的时候,会判断当前对象是否已经进行过Scavenges算法:
   1,进行过Scavenges算法,则会直接将from中的对象晋升到老生代
   2,没有进行过Scavenages算法,但是to区内存已经占用25%,则也会直接晋升到老生代

老生代标记清除和标记整理算法:
标记整理是第一次从根节点进行遍历,所有能被访问到的对象都会被打上标记,第二次遍历之前,对标记和未标记的对象的内存地址进行整理,标记状态的对象内存地址是连着的,未标记的对象也是连着的,然后第二次遍历,对标记的对象进行清理

垃圾回收算法是一次行执行完成的,也就是垃圾回收处理完成,才会出现主任务执行的情况,这种情况称为“全停顿”,为了减少垃圾回收带来的全停顿的影响,V8引入了增量标记,也就是标记和主任务交替执行。后面又引入了增量整理和延迟清除。