JS的垃圾回收机制
- JavaScript 是使用垃圾回收的语言,也就是说执行环境负责在代码执行时管理内存。
- 基本思路很简单:确定哪个变量不会再使用,然后释放它占用的内存。这个过程是周期性的,即垃圾回收程序每隔一定时间(或者说在代码执行过程中某个预定的收集时间)就会自动运行。
- 垃圾回收过程是一个近似且不完美的方案,因为某块内存是否还有用,属于“不可判定的”问题,意味着靠算法是解决不了的。
在浏览器的发展史上,用到过两种主要的标记策略:标记清理和引用计数。
标记清理
到了 2008 年,IE、Firefox、Opera、Chrome 和 Safari 都在自己的 JavaScript 实现中采用标记清理(或
其变体),只是在运行垃圾回收的频率上有所差异。
- 先标记内存中存储的所有变量。
- 然后,将所有在上下文中的变量,以及被在上下文中的变量引用的变量的标记去掉。
- 之后有标记的变量就是待删除的了,因为上下文中的变量都访问不到它们了。
- 随后垃圾回收程序做一次内存清理,销毁带标记的所有值并收回它们的内存。
引用计数
没那么常用的垃圾回收策略
思路:记录每个值被引用的次数。
- 一个引用值赋值给一个变量时,计数 +1
- 又赋值给另一个变量时,计数 +1
- 对该值引用的变量被其他值给覆盖了,计数 -1
最后:
当一个值的引用数为 0 时,就说明没办法再访问到这个值了,因此可以安全地收回其内存了。
垃圾回收程序下次运行的时候就会释放引用数为 0 的值的内存。
问题:
- 循环引用问题(对象 A 有一个指针指向对象 B,而对象 B 也引用了对象 A)
参考
《JavaScript高级程序设计(第4版)》 4.3 垃圾回收