了解js GC(垃圾回收♻️)机制

177 阅读2分钟

什么是GC机制

每当我们创建一个实体时(包括undefined)都会进行内存分配,而GC机制也就是Garbage Collection(垃圾回收)机制会在触发一定条件时进行无用变量的清理,从而释放内存避免消耗的内存过大造成系统崩溃

GC触发条件

百度上搜了很多,发现没有比较明确的答案,大多数答案都是来回复制。去google一搜果然还是google香。下面放出在stackoverflow上的回答 image.png 上面所说大致指出一种是新生代满了就会触发,或者是老生代中分配了N个字节时会触发。其中新老生代将在下面提到。第二种是tab标签处于非活动状态或在后台时将会被触发。除了这两个常见的之外,也会有一些其他的触发条件

具体回收机制

在当前V8引擎中采用的分代回收机制,会分为新生代和老生代。新生代通常存放存活时间较短的变量,而老生代存放存活时间较长变量。

新生代

新生代中会将空间一分为2分为from空间和to空间,当from空间被占满时,会开始将from空间中的活跃对象转移到to空间中,全部转移完毕后会进行原from空间内存的释放,随后交换两个空间循环往复。当一个对象存活经历过中间代并再次存活下来时,其将会被晋升到老生代,如下图

image.png

还有一种晋升到老生代的原因是其超过了新生代空间的25%,其也会被置于老生代中。

老生代

老生代中的非活动变量清除往往采用标记清除法,其会从根对象上进行查找对于其可达对象的引用标记为活动对象,那么未被标记过的对象也就是根对象访问不到的将会被清除掉。但也会因此造成地址碎片化,对此v8采用了新的方法为标记整理法,其会将所有存活对象向一端移动,随后释放掉其余内存,从而解决内存碎片化的问题,但由于进行了移动操作,也因此速度较慢。从而正常是采用标记清除法,只有在空间不足以对新生代晋升对象存放时才会进行标记整理法的应用。

增量式标记

由于在进行垃圾回收时会停止我们的应用逻辑,因此为了减轻对于应用逻辑js的执行,在对于老生代对象进行标记阶段采用了增量标记即执行一会儿就切换到应用逻辑先执行,进行切片式标记。