高级前端
js
【Q291】简述 node/v8 中的垃圾回收机制

简述 node/v8 中的垃圾回收机制

Issue 欢迎在 Gtihub Issue 中回答此问题: Issue 293 (opens in a new tab)

Author 回答者: shfshanyue (opens in a new tab)

v8 中的垃圾回收机制分为三种

  1. Scavenge,工作在新生代,把 from space 中的存活对象移至 to space
  2. Mark-Sweep,标记清除。新生代的某些对象由于过度活跃会被移至老生代,此时对老生代中活对象进行标记,并清理死对象
  3. Mark-Compact,标记整理。

相关链接

  1. 主流的垃圾回收机制都有哪些? (opens in a new tab)
  2. 各种编程语言的实现都采用了哪些垃圾回收算法 (opens in a new tab)

Author 回答者: wjw-gavin (opens in a new tab)

当一个函数执行结束之后,JavaScript 引擎会通过向下移动 ESP 来销毁该函数保存在栈中的执行上下文。 要回收堆中的垃圾数据,就需要用到 JavaScript 中的垃圾回收器了。 代际假说(The Generational Hypothesis),是垃圾回收领域中一个重要的术语,后续垃圾回收的策略都是建立在该假说的基础之上的,所以很是重要。 代际假说有以下两个特点:

  1. 大部分对象在内存中存在的时间很短,简单来说,就是很多对象一经分配内存,很快就变得不可访问;
  2. 是不死的对象,会活得更久。 在 V8 中会把堆分为新生代和老生代两个区域,新生代中存放的是生存时间短的对象,老生代中存放的生存时间久的对象。 ● 副垃圾回收器,主要负责新生代的垃圾回收。 ● 主垃圾回收器,主要负责老生代的垃圾回收。

全停顿 1620974853612-a480b43e-b3bb-452f-a502-3a0162548a7f

增量标记 1620975019709-efc33748-fbfc-4fb5-a19d-97abadbf8f97

使用增量标记算法,可以把一个完整的垃圾回收任务拆分为很多小的任务,这些小的任务执行时间比较短,可以穿插在其他的 JavaScript 任务中间执行,增强用户体验。

参考: 浏览器工作原理与实践 (opens in a new tab)