残缺高频题库仓库地址: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 内存透露常见起因
- 创立全局变量,且没有手动回收。
- 事件监听器 / 定时器 / 闭包等未失常清理。
- 应用 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
-
标记(Mark)
标记是找所有可拜访对象的过程。GC 会从一组已知的对象指针(称为根集,包含执行堆栈和全局对象等)中,进行递归标记可拜访对象。
-
革除(Sweep)
革除是将不可拜访的对象留下的内存空间,增加到闲暇链表(free list)的过程。将来为新对象分配内存时,能够从闲暇链表中进行再调配。
-
整顿(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 角色调换。
参考资料
- Memory Management
- Trash talk: the Orinoco garbage collector