垃圾回收机制、闭包、以及内存泄漏

Js中的垃圾回收机制

1.标记清除
工作原理:当变量进入环境时被垃圾回收器标记为‘进入环境’,离开环境时被标记为‘离开环境’,标记为‘离开环境’的变量被统一回收。
工作流程:
1.垃圾回收器将内存中所有存在的变量做标记
2.将内存中存在环境中的变量以及环境变量所引用的变量的标记去除
3.仍然存在标记的变量被视为‘离开环境’的变量
4.垃圾回收器完成内存清除工作,清除所有带标记的变量并回收其内存空间。

2.引用计数(低IE版本9.0)
工作原理:机制就是跟踪一个值的引用次数,当声明一个变量并将一个引用类型赋值给该变量时该值引用次数加1,当这个变量指向其他一个时该值的引用次数便减一。当该值引用次数为0时就会被回收。
工作流程:

  1. 声明了一个变量并将一个引用类型的值赋值给这个变量,这个引用类型值的引用次数就是1。
  2. 同一个值又被赋值给另一个变量,这个引用类型值的引用次数加1.
  3. 当包含这个引用类型值的变量又被赋值成另一个值了,那么这个引用类型值的引用次数减1.
  4. 当引用次数变成0时,说明没办法访问这个值了。
  5. 当垃圾收集器下一次运行时,它就会释放引用次数是0的值所占的内存。

内存泄漏问题
在IE9版本以前,DOM、BOM元素对象并非原生JS对象,而是由C++编写的COM对象形式实现,而COM对象采用的为该计数垃圾回收策略,从而容易循环引用导致内存泄漏问题;
那么何为循环引用?

function f(){
var a={},
var b={},
a.prop =b;
b.Prop = a;
}
该例子中,a的属性引用b,b的属性引用a,从而以计数原则,a、b的引用次数均为2,而且永远为2,垃圾回收机制无法回收该对象,从而造成的内存泄漏。

!!!DOM简单事件引起的内存泄漏
这里牵扯到闭包的问题,我们知道闭包是能使用外部变量的内部函数,因为闭包默认引用了外部函数的变量,所以及其容易循环引用造成内存泄漏问题。
window.onload = function outerFunction(){
var obj= document.getElementById(“eleId”);
obj.onclick = function innerfunction(){
console.log(obj.id);
}
}
该例子中,dom元素obj使用了引用了闭包,而闭包默认引用了外部变量(其中包含obj),如此一来,便形成了一个循环引用。
解决方案:
window.onload = function outerFunction(){
var obj= document.getElementById(“element”);
var id = obj.id;//将obj副本保存于变量id中,则不会使obj元素处理程序的闭包创建循环引用
obj.onclick = function innerfunction(){
console.log(id);
}
obj= null;//手动断开 obj 对 document.getElemengById(“element”)的引用
}

你可能感兴趣的:(前端js)