内存泄漏和垃圾回收

目录

垃圾回收机制

所谓的内存泄漏简单来说是不再用到的内存,没有及时释放。为了更好避免内存泄漏,我们需要搞清楚Javascript垃圾回收机制。

垃圾回收有两种方法:标记清除、引用计数。目前用的比较多得是标记清除,引用计数会存在循环引用的问题。
如:

var a = {}
var b = {}
a.n = b
b.f = a

当变量进入环境(例如,在函数中声明一个变量)时,就将这个变量标记为“进入环境”。从逻辑上讲,永远不能释放进入环境的变量所占用的内存,因为只要执行流进入相应的环境,就可能会用到它们。而 当变量离开环境时,则将其标记为“离开环境”。

垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记(当然,可以使用任何标记方式)。然后,它会清除环境中的变量以及被环境中的变量引用的变量的标记。而在此之后还带有标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。最后,垃圾收集器完成内存清除工作,销毁那些带标记的值并回收它们所占用的内存空间。

标记-清除算法:

  1. 垃圾回收机制维护一系列根节点,例如window、global对象等,这些根节点所占用的内存不会被回收;
  2. 从根节点出发,递归的检查子节点,根节点和所有子节点都标记为引用状态,内存不会被回收
  3. 所有没有标记的内存块,视为垃圾内存,自动回收,有系统重新分配。

常见的内存泄漏

  1. 声明全局变量
// (1) 直接声明全局变量
function foo(){
    name = 'xxx'
}
// (2) 通过this变量引入
function foo(name){
    this.name = name
}

foo('小明')

解决方案:var let const;如果不得不使用全局变量,引用之后,手动设置为null

  1. setTnterval中引用的变量和对象:未清除定时器,这些变量和对象会一直存在内存中

解决方案:clearInterval()清除定时器
3. dom事件没有移除:dom节点被移除但是事件依然存在内存中

解决方案:removeEventListener()
4. dom移除:移除没有释放子节点的父节点

var $ = document.getElementById;
var tree = $("#tree")
var leaf = $('#leaf') // leaf 是tree中的一个子节点
$('body').removeChild(tree) //tree不能被回收,因为leaf还在

  1. 闭包
    当对象销毁时,手动置为null

参考资料:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值