垃圾回收算法主要依赖于引用的概念。
回收思路
- 局部变量:局部变量只在函数执行的过程中存在。这种情况只要在函数执行结束就可以判断局部变量没有存在的必要了,然后回收其内存。
- 其他变量:主要通过跟踪变量,对不再有用的变量打上标记。实现上的不同主要是标记无用标量的策略不同。
标记清除(常用)
思路
”对象是否不再需要“ => ”对象是否可以获得“
垃圾回收器将定期从根(全局变量)开始,找所有从根开始引用的对象,然后找这些对象引用的对象……从根开始,垃圾回收器将找到所有可以获得的对象和收集所有不能获得的对象。
垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记。然后,它会去掉环境中的变量以及被环境中的变量引用的变量的标记。之后还有标记的变量被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。
引用计数垃圾收集
思路
“对象是否不再需要” => “对象有没有其他对象引用到它” => ”对象是否可以访问到“
如果没有引用指向该对象(零引用),对象将被垃圾回收机制回收。
方式
跟踪记录每个值被引用的次数。如果这个值的引用次数变为 0,说明已经没有办法访问到该值。
问题
对于循环引用的情况,由于两个变量都至少引用一次,所以在这种策略下永远不会被回收。
对于标记清除就不存在这种问题。函数调用返回之后,两个循环引用的对象从全局对象出发无法获取。因此,他们将会被垃圾回收器回收。
参考
-
《JavaScript 高级程序设计》