js 内存泄露
学习了:javascript 的内存泄露
1、什么是内存泄漏
先上定义,内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。
内存泄漏问题很常见的,通俗表现就是用着用着任务管理器里的内存占用越来越大~~~越来越大~~~比如侠客风云传刚出那会儿,玩着玩着就好多G内存占用了,这就是内存泄漏。
javascript是一种高级语言,它不像C语言那样要手动申请内存,然后手动释放,js在声明变量的时候自动会分配内存,普通的类型比如Number,一般放在栈内存里,对象放在堆内存里,声明一个变量,就分配一些内存,然后定时进行垃圾回收,js的内存管理可以参考官方文档。
2、查找内存泄漏点
发现了内存用着用着暴涨,然后去找内存泄漏的时候,其实相当于一个桶在漏水,好多个小窟窿,你得一个个的找那些窟窿在哪里,堵上一个好一点儿,堵得差不多了,才有效果。
内存泄漏问题可以从常见泄漏点和代码逻辑导致的泄漏点两方面来查找。
2.1)常见泄漏点
闭包:闭包的概念是我有个代码区域,使用了外层区域某个变量,那么这个代码区域执行完之前,外层的那个变量肯定不能被释放,这就是闭包。
定时器:定时器是万恶之源。。。this.timer = setInterval(()=>{console.log('i am still alive!')}, 500),千万注意this.timer = null并不能清理掉定时器!定时器这玩意儿还在,只是你找不到它了!一定要写clearInterval(this.timer)才能清理掉!(可以在控制台试一下...)
未捕获的异常/console.error:这玩意儿打log在控制台里,你随便什么时候打开控制台,都能看见,因为这玩意儿存起来了啊!这玩意儿进内存了啊!所以才什么时候打开都有啊!坑~
对DOM的引用:jQuery时代,有好多对DOM的引用,this.testDom = $('#test')就拿到DOM了,这个跟闭包搅合在一起比较占用内存,ES6有个语法叫weakMap,就是为了解决DOM引用占内存的问题,可以看一下。
2.2)代码逻辑导致的泄漏点
代码逻辑大家都不一样,通用的方法是先找出你页面逻辑里的高频使用的功能点,写个脚本,脚本里疯狂的重复操作,然后看这个功能点导致的内存消耗。发现即解决。
3、效果验证
最后,需要压测或者采集数据来验证自己的优化效果。
总之内存泄漏的查找是个精细活儿,没用什么点一下就能都帮你分析出来的工具,很多泄漏点其实都深埋在业务逻辑当中,只有写的人才能找出来。