垃圾回收
原理
- 执行环境会找出那些
不再
继续使用的变量,然后释放
其占用的内存。
策略
引用计数垃圾收集
原理
- 跟踪每一个值
被引用
的次数 此算法把“对象是否不再需要”简化定义为“对象有没有其他对象引用到它”。如果没有引用指向该对象(零引用),对象将被垃圾回收机制回收。
局限性
-
循环引用 无法处理循环引用的事例。两个对象被创建,并
互相引用
,形成了一个循环。它们被调用之后会离开函数作用域,所以它们已经没有用了,可以被回收了。然而,引用计数算法考虑到它们互相都有至少一次
引用,所以它们不会被回收。标记清除
原理
假定设置一个叫做根root
的对象(在Javascript里,根是全局对象)。垃圾回收器将定期从根开始,找所有从根开始引用的对象,然后找这些对象引用的对象从根开始,垃圾回收器将找到所有可以获得的对象和收集所有不能获得的对象。
局限性
那些无法从根对象查询到的对象都将被清除 。
v8垃圾回收机制
栈内存的回收
栈内存调用栈上下文切换后,栈顶的空间就会自动
被回收。操作系统会自动进行内存分配和内存释放。
堆内存的回收
新生代内存的回收
- 副垃圾回收器 -
Scavenge
算法
- 标记活动对象和非活动对象
- 复制 from space 的活动对象到 to space 并对其进行排序
- 释放 from space 中的非活动对象的内存
- 将 from space 和 to space 角色互换
老生代内存的回收
- 主垃圾回收器 -
Mark-Sweep
&Mark-Compact
- 标记阶段:对老生代进行第一次扫描,标记
活动对象
。 - 清理阶段:对老生代进行第二次扫描,清除未被标记的对象,即清理
非活动对象
。 - 活动对象整理阶段,将所有的活动对象往一端移动,移动完成后,直接清理掉边界外的内存。
优化 Orinoco
1. 增量标记
增量标记将原本的标记全堆对象拆分为一个一个任务,让其穿插在JavaScript应用逻辑之间执行。
2.懒性清理
将一次停顿进行的过程分为了多步,每次执行完一小步就让运 行逻辑执行一会,就这样交替运行。
3.并发
4.并行
新生代对象晋升到老生代的条件
- 第一个是判断是对象否已经经过一次
Scavenge
回收。若经历过,则将对象从From空 间复制到老生代中;若没有经历,则复制到To空间。 - 第二个是To空间的内存使用占比是否超过限制。当对象从From空间复制到To空间时,
若To空间使用超过
25%
,则对象直接晋升到老生代中。设置25%的原因主要是因为算法结束 后,两个空间结束后会交换位置,如果To空间的内存太小,会影响后续的内存分配。