js垃圾回收机制/内存泄漏【易懂-个人总结】

JS 的垃圾回收机制是为了以防内存泄漏
一、我们先来简单了解下内存泄漏:

概念:就是任何对象在我不需要它的时候,他还存在
内存泄露是老浏览器(主要是IE6),由于垃圾回收有问题导致的bug,跟JS本身没有关系。

什么会导致内存泄漏及解决方法:
1、比如引用计数策略的垃圾回收机制中,如果两个对象之间形成了循环引用,那么这两个对象都无法被回收。使用闭包比较容易造成循环引用(彼此引用彼此保留),本质不是闭包造成的,但过多使用闭包容易导致内存泄漏。
解决:让被迫留在内存中的变量对象=null,手动清除

2、setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏。
老的IE6用引用计数,无法处理循环引用,现代的浏览器使用了更先进的垃圾回收算法(标记清除),已经可以正确检测和处理循环引用了。

3、意外的全局变量:①未定义的全局变量 ②函数内的声明忘记var
解决:1、使用严格模式,防止意外的全局变量 2、如果一定要使用全局变量,在使用完赋值为null清除。

二、垃圾回收机制

简单的说,当一个函数被执行完后,其作用域会被收回,如果形成了闭包,执行完后其作用域就不会被收回。
垃圾回收的核心思路清理调内存中不在被引用的值。通俗的讲,就是把内存中没用的值,都清理掉!
那我们怎么判断它就没有用了呢?
①对于局部变量,那么它在函数调用完之后,就没用了(你都调用完啦,那要你有什么用呢!)
②对于全局变量,在浏览器把页面卸载掉的时候消失,都要卸载页面了,这个过程肯定会消耗比较大,所以会按照固定时间,也就是周期性的进行回收。
闭包不能被回收,占用的不能被回收。
————————————————

从内存角度:
栈内存
-自动分配内存,页面打开就形成,只有页面关闭才释放
函数块级私有上下文:
一般代码执行完,就被释放。
如果被上下文以外的占用,不仅这个东西不能释放,私有上下文也不能释放。

堆内存-动态分配内存,主要看是否被占用
如果没被占用,浏览器在空闲时回收,如果被占用,就无法回收
为减少内存,可以用fn=null 手动清除之前的引用。

按变量来说,局部变量函数执行完就被释放,全局变量等到页面卸载就进行周期性回收。闭包不能被回收,被占用的不能被回收。

JS 中最常见的垃圾回收方式是标记清除

标记清除:
工作原理:是当变量进入环境时,将这个变量标记为“进入环境”。当变量离开环境时,
则将其标记为“离开环境”。标记“离开环境”的就回收内存。

工作流程:给存储在内存中的所有变量都加上标记,然后,它会去掉处在环境中的变量及【被(环境中的变量)引用的变量(闭包)】的标记。剩余的(再被加上标记的)被视为准备删除的变量,因为是环境中的变量已经无法访问到这些变量了。垃圾回收器清理销毁带标记值并释放内存。

此外我们再了解一下引用计数的原理把!
引用计数:
垃圾回收器定期扫描对象,并计算了每个值被引用的次数(引用一次加1,反之减1)。如果一个对象的引用次数为 0(没有被占用),或对该对象的唯一引用是循环的,那么该对象的内存即可回收。
一般老的浏览器(IE6)用引用计数,使用闭包容易造成循环引用(彼此引用彼此保留),这两个对象都无法回收,导致内存泄漏。

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值