longlongyu
for me

JavaScript的垃圾回收机制

2018-08-08 learn javascript garbage collecation
Word count: 1,279 | Reading time: 4min

JavaScript 是一门很容易上手的语言。

他有着自动垃圾回收机制 (GC:Garbage Collecation) ,使我们撰写代码不用去手动去释放内存来管理和分配内存。因为这些全由 JavaScriptGC 来帮我们完成了,我们只需要快乐的敲打代码就好了。

然而, JavaScriptGC 虽然很便利,却也埋下了诸多隐患。例如,内存泄漏就是一个我们常常遇见的问题,让很多新手程序员对此一头雾水。而如果你了解了 JavaScript 的垃圾回收机制,你就能更好的避免和解决此类的问题,从而达到性能的优化。

JavaScript 回收机制的原理

JavaScript 的垃圾回收机制是必要的,因为每次创建字符串、数组或对象时,JavaScript 的解释器并须从系统中分配内存来存储这些数据。而如果不释放这些数据,就会致使内存被过快消耗完,从而导致系统崩溃。

JavaScript 垃圾回收的机制很简单: 就是在内存中找出那些不再使用的变量,然后将其占用的内存释放。

但是,这个过程却不是实时的。因为如果要时刻检测变量的状态,无疑会带来巨大的内存开销。为此, JavaScript 会周期性的进行一次检测,以此来释放那些已不被使用的内存。

具体行为

目前各大浏览器通常采用以下两种垃圾回收机制,来回收我们的内存,它们分别是: 标记清楚法和引用计数法。

标记清楚法

这是 JavaScript 中最常见的垃圾回收方式。当变量进入执行环境时,就标记这个变量为”进入环境”,从逻辑意义上来说,在执行环境中的变量并不需要我们去回收它的内存,因为只要执行流进入相应的环境,就有可能会被使用。而当它们离开环境时,则我们就可以回收这些内存,所以将其标记为”离开环境”。以方便在后面的步骤中释放它们。

之后在垃圾回收机制在执行时,会给内存中的所有变量加上标记。然后,去掉环境中的变量以及被环境中变量所引用的标记。而此外被加上标记的标记的变量,都视为待删除的变量,环境中的变量已经无法访问到这些变量了。

最后将那些标记的值销毁,回收其占用的内存,完成垃圾回收工作。

1
2
3
4
function test() {
var a = 0;//进入执行环境,被标记为"进入环境";
}
test();//执行 执行完后,a被标记为"离开环境",等待释放

引用计数法

这是一种不太常见的垃圾回收策略。

引用计数的策略是跟踪记录每个值被引用的次数。当声明了一个变量并将一个引用类型赋值给该变量时,则这个值的引用次数就是1。相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值的引用次数就减1。当这个引用次数变成0时,则说明没有办法再访问这个值了,因而垃圾回收机制就可以判断这个值为可回收。在下次垃圾回收机制在执行时,它会释放那些引用次数为0的值所占的内存。

不过该策略有一个缺陷:

1
2
3
4
var A = new A();
var B = new B();
A.a = B;
B.b = A;// 此时A、B引用次数为2

可以看到,由于对象A、B都有属性互相引用,从而导致引用次数不会为0,所以垃圾回收机制不会去回收此内存,从而导致了内存泄漏。

因此现在基本上所有浏览器都采用第一种方式来清楚内存。

GC 的缺陷

和其他语言一样,javascriptGC 策略也无法避免一个问题:

GC 执行时,会停止响应其他操作。

虽然这是为了安全考虑,但也因此使 JavascriptGC100ms 甚至以上,对一般的应用还好,但如果是 JS 游戏,动画等对连贯性要求比较高的应用,就会带来麻烦。

这也是目前 GC 引擎需要优化的点。

GC优化策略

目前有两种 GC 优化策略:

分代回收

这个方法参考了 Java 的回收策略。就是通过区分对象的状态“临时”,还是“持久”;多回收“临时对象”区,少回收“持久对象”区,减少每次需遍历的对象,从而减少每次 GC 的耗时。

增量GC

这个方案的思想很简单,就是“每次处理一点,下次再处理一点”,如此类推。

这种方案,虽然耗时短,但中断较多,带来了上下文切换频繁的问题。

Author: Longlongyu

Link: https://longlongyu.github.io/2018/08/05/GarbageCollecation/

Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.

< PreviousPost
摘要图片测试
NextPost >
关于HTML5语义化
CATALOG
  1. 1. JavaScript 回收机制的原理
  2. 2. 具体行为
    1. 2.1. 标记清楚法
    2. 2.2. 引用计数法
  3. 3. GC 的缺陷
  4. 4. GC优化策略
    1. 4.1. 分代回收
    2. 4.2. 增量GC