1.垃圾回收机制是干什么用的?
为了防止内存泄漏,不占用内存不定期的会找不再引用的变量(生命周期结束了),并释放他们所指向的内存。 局部变量生命周期在他们被引用执行之后结束,全局变量会在到浏览器关闭。
2.如何使用垃圾回收机制
(1)标记清除
function text(){
var a=10 //被标记‘进入环境’
}
text() //被执行之后标记‘离开环境’,被自动释放其内存
function text2(){
var b='hello,world';
return b; //即使出了环境,也保留着b被抛出到根中,所以不会被释放。
}
(2)引用计数 通过计数的方法来判断是否可以清除
let arr=[1,2,3,4];
arr=null;
//第一次赋值被定义时为1,通过手动重置arr为null,解除引用。这样次数就变成了0,可以释放内存。
weakmap
除了全局变量也可以手动设置不计入回收机制的。
const wm=new WeakMap();
const element=document.getElementById('title')
wm.set(element,'some information')
wm.get(element)
先新建一个weakpack实例,再写一个附加信息一起存入weakmap,这时对element的引用就是弱引用不被记入垃圾回收机制。可以对此手动回收。
例子:
node --expose-gc
process.memoryUsage();//查看内存占用的初始状态,heapUsed为4M左右
let wm=new WeakMap();//undefined
let b=new Object();//undefined
wm.set(b,new Array(5*1024*1024));//在weakmap里添加一个键值对,对象是b,键值是一个很大的数组.......
WeakMap{}
b=null;//解除对b的引用
b为空
这时查看process.memoryUsage()又回到了4M左右
其他的手动解决内存泄露方式:
1.全局变量引起的内存泄露
原因:全局变量不会被回收
解决:使用严格模式
2.闭包引起
原因:活动对象被引用,闭包的变量不会被释放,
解决:将活动对象赋值为null
3.被清理的dom元素引用
原因:虽然dom被删掉,但对象中还存在dom的引用
解决:将对象赋值为null
4.定时器和回调
原因:定时器和回调都是闭包
解决:清理定时器clearInterval和把回调赋值为null。