0
点赞
收藏
分享

微信扫一扫

js垃圾回收和内存泄漏

witmy 2022-01-20 阅读 54

js垃圾回收

浏览器的 Javascript 具有自动垃圾回收机制(GC:Garbage Collecation),垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存。但是这个过程不是实时的,因为其开销比较大并且GC时停止响应其他操作,所以垃圾回收器会按照固定的时间间隔周期性的执行。
如何辨别哪些变量可以回收?

标记清除

function fn(){
var a = 10 ;       // 被标记 ,进入环境 
var b = 20 ;       // 被标记 ,进入环境
}
fn();            // 执行完毕 之后 a、b又被标离开环境,被回收。

到目前为止,IE9+、Firefox、Opera、Chrome、Safari 的 JS 实现使用的都是标记清除的垃圾回收策略,只不过垃圾收集的时间间隔互不相同。

引用计数

function fn() {
    var a = {};    // a指向对象的引用次数为1
    var b = a;     // a指向对象的引用次数加1,为2
    var c = a;     // a指向对象的引用次数再加1,为3
    var b = {};    // a指向对象的引用次数减1,为2
}

内存泄漏

vue中内存泄漏问题

  • 如果在mounted/created钩子中使用 JS 绑定了DOM/BOM对象中的事件,需要在 beforeDestroy中做对应解绑处理;
  • 如果在 mounted/created钩子中使用了第三方库初始化,需要在 beforeDestroy中做对应销毁处理(一般用不到,因为很多时候都是直接全局 Vue.use);
  • 如果组件中使用了 setInterval,需要在 beforeDestroy中做对应销毁处理;
// 例如:
  mounted() {
    this.ele = document.querySelector('.home')
    // 添加滚动监听事件
    this.ele.addEventListener('scroll',this.handlerscroll)
  },
  // 页面销毁时,移除监听事件
  destroyed(){
	this.ele.removeEventListener('scroll',this.handlerscroll)
  }

js中内存泄漏问题

1. 意外的全局变量

function fn() {
	a = 1
}
fn()
解决:window.a = null
或者:在js文件开头添加 ‘use strict',开启严格模式。

fn 执行的时候,由于内部变量没有定义,所以相当于 window.a= 1,函数执行完毕,本应该被销毁的变量 a 却永久的保留在内存中了。
另一种

function fn(){
	this.a = 1	// this指向window
}
fn()
解决:window.a = null

2. 闭包

    function fn() {
        var a = 2
        function fn2() {
            console.log(++a);
        }
        return f2
    }
    var f = fn()
    f() 
    解决:f = null

3. DOM泄漏

var body = document.querySelector('body')
var father = document.querySelector('.father')
var son = document.querySelector('.son')
father.appendChild(son)
body.removeChild(father);
解决:father = null

4. 计时器没有及时关闭

setInterval((function(){
	console.log(1)
}, 1000)
解决:不需要的时候,调用clearInterval
举报

相关推荐

0 条评论