乐趣区

关于gc:垃圾回收机制

残缺高频题库仓库地址:https://github.com/hzfe/aweso…

残缺高频题库浏览地址:https://febook.hzfe.org/

相干问题

  • 什么是内存透露
  • 常见的垃圾回收算法
  • 如何排查内存透露

答复关键点

援用计数法 标记革除法 Mark-Compact(标记整顿) Scavenger(清道夫)

GC(Garbage Collection,垃圾回收)是一种内存主动管理机制,垃圾回收器(Garbage Collector)能够主动回收调配给程序的曾经不再应用的内存。常见的 GC 算法有援用计数法和标记革除法等。V8(JavaScript 引擎,提供执行 JavaScript 的运行时环境)的垃圾回收器算法次要由 Mark-Compact 和 Scavenger 形成。

知识点深刻

1. 内存透露

内存透露是指,该当被回收的对象没有被失常回收,变成常驻老生代的对象,导致内存占用越来越高。内存透露会导致应用程序速度变慢、高延时、解体等问题。

1.1 内存生命周期

  1. 调配:按需分配内存。
  2. 应用:读写已调配的内存。
  3. 开释:开释不再须要的内存。

1.2 内存透露常见起因

  • 创立全局变量,且没有手动回收。
  • 事件监听器 / 定时器 / 闭包等未失常清理。
  • 应用 JavaScript 对象来做缓存,且不设置过期策略和对象大小管制。
  • 队列拥塞所带来的生产不及时问题。

2. Reference Counting(援用计数)

Reference Counting 是常见的垃圾回收算法,其外围思路是:将资源(比方对象)的被援用次数保存起来,当被援用次数为零时开释。该办法的局限性:当呈现 循环援用 时,相互援用的对象不会被回收。

3. V8 垃圾回收机制

V8 中有两个垃圾收集器。次要的 GC 应用 Mark-Compact 垃圾回收算法,从整个堆中收集垃圾。小型 GC 应用 Scavenger 垃圾回收算法,收集新生代垃圾。

两种不同的算法应答不同的场景:

  • 应用 Scavenger 算法次要解决 存活周期短 的对象中的可拜访对象。
  • 应用 Mark-Compact 算法次要解决 存活周期长 的对象中的不可拜访的对象。

因为新生代中存活的可拜访对象占多数,老生代中的不可拜访对象占多数,所以这两种回收算法配合应用非常高效。

3.1 分代垃圾收集

在 V8 中,所有的 JavaScript 对象都通过 来调配。V8 将其治理的堆分成两代:新生代和老生代。其中新生代又可细分为两个子代(Nursery、Intermediate)。

即新生代中的对象为存活工夫较短的对象,老生代中的对象为存活工夫较长或常驻内存的对象。

3.2 Mark-Compact 算法(Major GC)

Mark-Compact 算法能够看作是 Mark-Sweep(标记革除)算法和 Cheney 复制算法的联合。该算法次要分为三个阶段:标记、革除、整顿。

image

  1. 标记(Mark)

    标记是找所有可拜访对象的过程。GC 会从一组已知的对象指针(称为根集,包含执行堆栈和全局对象等)中,进行递归标记可拜访对象。

  2. 革除(Sweep)

    革除是将不可拜访的对象留下的内存空间,增加到闲暇链表(free list)的过程。将来为新对象分配内存时,能够从闲暇链表中进行再调配。

  3. 整顿(Compact)

    整顿是将可拜访对象,往内存一端挪动的过程。次要解决标记革除阶段后,内存空间呈现较多内存碎片时,可能导致无奈调配大对象,而提前触发垃圾回收的问题。

3.3 Scavenger 算法(Minor GC)

V8 对新生代内存空间采纳了 Scavenger 算法,该算法应用了 semi-space(半空间)的设计:将堆一分为二,始终只应用一半的空间:From-Space 为应用空间,To-Space 为闲暇空间。

新生代在 From-Space 中调配对象;在垃圾回收阶段,查看并按需复制 From-Space 中的可拜访对象到 To-Space 或老生代,并开释 From-Space 中的不可拜访对象占用的内存空间;最初 From-Space 和 To-Space 角色调换。

参考资料

  1. Memory Management
  2. Trash talk: the Orinoco garbage collector
退出移动版