记JS内存管理策略

231 阅读2分钟

这是我参与更文挑战的第3天,活动详情查看:更文挑战

随着 JS 越来越多的用于端开发(比如 electron),前端也需要更多的关注内存问题,了解 JS 内存管理的实现,有助于我们避免写出存在内存泄露的代码。

JS 有如下两种自动垃圾收集机制:

1. 标记清除

标记清除是说当变量进入某个执行环境时,会对该变量标记为“进入环境”,离开时标记为“离开环境”。可以采用任意的方式来实现,然后,垃圾收集器(GC) 运行时,就可以释放那些标记成“离开环境”的变量。

上述任意方式举例:先给内存中的所有变量加上标记,然后清除被环境中变量引用的变量的标记,最后再回收还存在标记的变量即可。

到2008年,主流浏览器都使用标记清除(或类似)的垃圾收集策略。

2. 引用计数

另一个方式是引用计数,每当值被赋值给一个变量时,该值的引用数量就会加1,当指向这个值的变量又取另一个值时,原先值的引用数减1。因而当引用数为0时,表示这个值不再被使用,当垃圾收集器运行时,就会回收这个这个值所占的内存空间。

引用计数有个严重的问题:循环引用,即对象 A 中的指针指向 B,B 中的指针指向 A,这时候 A、B 的引用数始终不为0,因此也就不会被回收。

3. 启示

当我们了解了 JS 内存管理策略后,就可以有意识在写代码时避免内存泄露问题,比如:

  • 不要在全局存放过多或过大的值,因为这么做标记清除和引用计数策略都会失效,变量不能被回收;
  • 当大的值不再使用时,注意将变量设置成 null,这样当该值脱离运行环境时,所占的内存就会被 GC 回收。

参考:红宝书第4章节-变量、作用域和内存问题