V8引擎垃圾回收机制

299 阅读2分钟

前言

javascript中的内存管理是自动执行的。那么这些基本类型、对象、函数所占用的内存是如何被释放的呢?我们以v8引擎的垃圾回收机制来解释这个过程。

内存查看

如果我们想查看当前程序的内存使用情况,我们可以通过process.memoryUsage()来查看。

console.log(process.memoryUsage());

// 输出结果
{ 
  rss: 19570688,
  heapTotal: 6537216,
  heapUsed: 3945144,
  external: 8272 
}

heapTotal是总共分配的堆内存;heapUsed是当前使用的堆内存。

堆内存分代

在v8引擎中,堆内存分为两个部分:新生代内存空间和老生代内存空间。其中新生代内存空间又分为from区和to区,这两个区大小一样。

  • 新生代内存
    • from区
    • to区
  • 老生代内存

垃圾回收机制

新生代回收机制

新创建的内存都是在from区,隔一段时间垃圾回收机制启动,把当前有引用的对象复制到to区,没有引用的就会被清除。此时,to区和from区互相转换(原来的to区变成新的from区,原来的from区变成新的to区)。如果一个对象在from区和to区移动次数达到5次就会被移动到老生代内存空间(说明它长时间都会存在当前环境中)

老生代回收机制

老生代回收机制采用的是标记清除算法(Mark Sweep),先将存活的对象进行标记,清除时只清除没有标记的(老生代中都是生命周期长的对象,刚好死亡的对象少),不过此时会出现内存不连续的情况,如果此时需要放一个大对象,则放不下,从而导致再次引起回收。然而这次回收是不必要的。因此又产生了标记整理算法(Mark Compact)。先将死亡的对象进行标记,然后将存活得对象往一段移动,移动完成后,清理掉边界外的内存。