js 垃圾回收机制
像C语言这样的底层语言一般都有底层的内存管理接口,比如 malloc()和free()。 js 是在创建变量时自动进行了分配内存,并且在不使用它们时自动释放。 释放的过程称为垃圾回收。
原理:垃圾收集器会按照固定的时间间隔,找出不再继续使用的变量,释放其占用的内存。
标记清除
- 垃圾收集器在运送的时候会给存储在内存中的所有变量加上标记
- 去掉环境中的变量以及被环境中的变量引用的变量的标记,在此之后再被加上标记的变量被视为准备删除的变量
- 最后,垃圾收集器完成内存清除工作,销毁带标记的值并回收他们所占用内存空间
08年为止,IE、Firefox、Opera、Chrome 和Safari 的JavaScript 实现使用的都是标记清除式的垃圾收集策略,只是垃圾收集的时间间隔不同
引用计数
引用计数的原理是记录每个值被引用的次数。当某个值的引用次数变成 0 时,说明已经没有对这个变量的引用。
垃圾收集器下次运行时,会释放引用次数为 0 的值所占用的内存。
存在的主要问题:循环引用
function p() {
var a = new Object()
var b = new Object()
a.props1 = b
b.props2 = a
}
// 函数被调用后,a 和 b 的引用次数永远不会是 0, 如果函数被重复多次调用,会导致大量内存得不到回收。
IE中,BOM 和 DOM 中的对象是使用 C++ 以 COM (Component Object Model 组件对象模型)对象的形式实现的,COM 对象的垃圾回收机制采用的是引用计数,即使 IE 的 js 引擎采用标记清除,IE 中涉及 COM 对象,仍然会有引用计数的问题。后来,IE9 把BOM 和DOM 对象都转换成了真正的JavaScript 对象。
优化内存方式:【解除引用
将变量设置为 null,可以切换变量与它此前引用的值之间的链接。解除引用不会自动回收该值所占用的内存,只是会让值脱离执行环境,垃圾收集器下次运行的时候会将其回收。
function A() {
return function() {
}
}
var m = A()
m = null
A函数在执行完毕后,活动对象不会被销毁,因为匿名函数的作用域链仍在引用这个活动对象,直到匿名函数被销毁后, A的活动对象才会被销毁。 将 m 设置为 null, 解除该函数的引用,等于通知垃圾回收器将其清除
网友评论