如何判断内存泄漏?内存发生变化?如何检测内存变化?
const arr = [];
for(let i=0;i<10*10000;i++){
arr.push(i);
}
function bind(){
//模拟一个比较大的数据
const obj = {
str: JSON.stringify(arr);
}
window.addEventListener('resize',()=>{
console.log(obj);
})
}
let n = 0;
function start(){
setTimeout(()=>{
bind();
n++;
//执行50次
if(n<50){
start();
}else{
alert('done')
}
},200);
}
document.getElementById('btn').addEventListener('click',()=>{
start();
});
在页面memory中看内存变化 检测内存变化
- 如果内存泄漏,会一直上升
- 检测工具:wangEditor检测内存泄漏
内存泄漏场景有哪些呢?(Vue为例)
- 被全局变量、函数引用,组件销毁时未清除
- 被全局事件、定时器引用,组件销毁时未清除
- 被自定义事件引用,组件销毁时未清除
data(){
return {
arr:[10,20,30],
intervalId: 0
}
},
methods(){
window.arr = this.arr;//全局变量、函数引用
printArr(){
console.log(this.arr);
}
},
mount(){
//会导致内存泄漏
window.addEventListener('resize',this.printArr)
//定时器使用,会发生内存泄漏
setInterval(()=>{
console.log(this.arr);
},100);
},
//页面销毁前,清空数据
beforeUnmount(){
window.arr = null;
window.printArr = null;
if(this.intervalId){
clearInterval(this.intervalId);
}
window.removeEventListener('resize',this.printArr);
}
重点
- 前几年前端不太注重内存泄漏,因为不像后端7*24持续运行
- 近几年前端功能不断复杂,内存问题也要重点考虑
拓展:WeakMap WeakSet(弱引用)
我们常用的对象Object,是由key:value集合组成的,但key只能是字符串,有很大的使用限制。当我们需要其他类型的数据做key值时,就需要用到数据结构Map,它支持把各种类型的值,当做键。
var map = new Map();
var zhang = {name:'张三'};
var li = {name:'李四'};
map.set(zhang,zhangsan);
map.set(li,lisi);
console.log(map.get(zhang)); //{name:'zhangsan'}
console.log(map.get(li)); //{name:'lisi'}
除了通过set还可以通过new Map添加成员变量
weakMap与map的区别:
- WeakMap只接受对象作为key,如果设置其他类型的数据作为key,会报错。
- WeakMap的key所引用的对象都是弱引用,只要对象的其他引用被删除,垃圾回收机制就会释放该对象占用的内存,从而避免内存泄漏。
- 由于WeakMap的成员随时可能被垃圾回收机制回收,成员的数量不稳定,所以没有size属性。
- 没有clear()方法
- 不能遍历