yjjnls/Notes

View on GitHub
lanauge/gc.md

Summary

Maintainability
Test Coverage
# Node.js
V8内存分为新生代与老生代,新生代为存活时间较短的对象,老生代是存活时间较长的对象。各自采用不同的垃圾回收方法。

## 新生代
### Scavenge算法
新生带采用Scavenge算法。将新生代分为from和to两个区域,分配内存时,从from区域开始分配。执行gc时,检查from区域的活对象(通过有向图,图上的对象表示有引用,就是活对象),将活对象拷贝到to区域,释放from区域的内存,再交换from和to。

特点:牺牲空间换取时间(每次只有一般内存能用),适合于短生命周期的对象。

## 老生代
### 晋升
新生代中的对象从from拷贝到to之前要经过检查,是否满足条件能够移动到老生代中。  
有以下两个标准:
1. 对象是否经历过Scavenge,通过查看对象的地址来判断。
2. to空间内存占比超过限制。如果to空间占比超过25%,则该对象直接晋升到老生代。

### Mark-Sweep
标记阶段遍历堆中所有活着的对象,之后在清除阶段,只清除没有被标记的对象。  
Mark-Sweep只清理死对象,因为死对象在老生代中只占一小部分,而活对象在新生代中只占一小部分。

缺点:清理后会产生内存碎片。   
参考:黑白灰标记  [V8垃圾回收机制简介](https://www.cnblogs.com/wolfx/p/5919574.html)   

### Incremental Marking
老生代遍历标记时,需要把业务逻辑停下来,这样会造成卡顿时间较长。一种解决方法就是把分片的方式,让gc和业务逻辑交替运行。