js内存泄漏:在js内存中 有一个内存垃圾回收机制: 垃圾回收期会定期扫描内存,当内存中某个值被设置为0就会将其进行回收。而这个设置为0是什么设置为0呢。
这里的设置为0指的是 例如我有两段代码
第一段:没有内存泄漏
let num = 0 function change(){ let my_num = 123 定义一个没有被引用的变量 也就是说这个变量没有被其他变量所引用/使用 只是单纯的定义了一个数值变量并且没有使用 num = 300 } change() 调用这个函数
第二段: 有内存泄漏
let num = 100 function change(){ let my_num = 200 定义一个局部变量 num = my_num 局部变量被外部变量引用 } change()
通过上边两段代码解释一下js的垃圾回收机制 js的垃圾回收机制一共分为两种 分别是标记清除和引用计数
标记清除 当变量进入环境时(例如,在函数中声明一个变量),将这个变量标记为“进入环境”。当变量离开环境时(变量不参与运行),则将其标记为“离开环境”。标记“离开环境”的就回收内存。
引用计数 就是 每当我们调用了这个函数后 这个函数内部每声明一个变量都会这个变量添加一个值为0的引用次数 上边也提到了垃圾回收机制中 会每过一段时间都会对内存进行扫描 当变量的引用次数为0时 就会把这个变量进行清除回收 而这个引用次数 则是每被引用一次 则这个引用次数+1 当引用的变量清除后 则-1 当被回收机制检测为0时则清除
内存泄漏的几种情况:
1. 闭包中未释放的变量
2. 没有被清除的定时器
3. 意外的全局变量 : 例如在一个函数中给window对象上挂载一个变量 而window对象指向全局
4. 给DOM对象添加的属性是一个对象的引用 例如
let obj = {...} let document.querySelector('.idname').property = obj 如果DOM不消除 则 这个obj会一直存在 造成内存泄漏 ( 这里的DOM元素的property属性是DOM元素自带的属性 html自带的dom属性会自动转换成property)
5. DOM对象和js对象互相引用
function testObject(element) { this.elementReference = element; // 为testObject(js)对象的属性绑定element(DOM)对象 element.property = this; // 为element(DOM)对象的属性绑定testObject(js)对象 } new testObject(document.getElementById('idname'));
4和5的 解决方案 :在window.onunload事件中写入下边的代码 document.getElementById('idname').property = null; 将DOM元素的property属性设置为空
6. 反复重写同一个属性会造成内存大量占用(但关闭IE后内存会被释放)
例如 一个 for循环 for(let i = 0 ; i < 5000; i ++){ hostElement.text = ' asdfgadsf ' }