浏览器内存过高问题

最近两天被一个问题给整的焦头烂额,做了一个功能,每次使用此功能浏览器的使用内存就直线飙升。看了一堆资料总结了点排查内存泄露的东西,在此做个记录

内存过高的原因

首先发现内存过高先要排查原因,可以打开浏览器自带的任务管理器Shift+Esc
找到你对应的页面,右击可以监控需要看的东西。我这里排查后发现是js使用的内存一直在叠加也就是js内存泄露
浏览器内存过高问题_第1张图片

js内存泄露

看了几篇博客大概说是造成js内存泄露一共五种
1. 意外的全局变量
全局变量的生命周期最长,直到页面关闭前,它都存活着,所以全局变量上的内存一直都不会被回收

当全局变量使用不当,没有及时回收(手动赋值 null),或者拼写错误等将某个变量挂载到全局变量时,也就发生内存泄漏了

2. 遗忘的定时器
setTimeout 和 setInterval 是由浏览器专门线程来维护它的生命周期,所以当在某个页面使用了定时器,当该页面销毁时,没有手动去释放清理这些定时器的话,那么这些定时器还是存活着的

也就是说,定时器的生命周期并不挂靠在页面上,所以当在当前页面的 js 里通过定时器注册了某个回调函数,而该回调函数内又持有当前页面某个变量或某些 DOM 元素时,就会导致即使页面销毁了,由于定时器持有该页面部分引用而造成页面无法正常被回收,从而导致内存泄漏了

如果此时再次打开同个页面,内存中其实是有双份页面数据的,如果多次关闭、打开,那么内存泄漏会越来越严重

而且这种场景很容易出现,因为使用定时器的人很容易遗忘清除

3. 使用不当的闭包
函数本身会持有它定义时所在的词法环境的引用,但通常情况下,使用完函数后,该函数所申请的内存都会被回收了

但当函数内再返回一个函数时,由于返回的函数持有外部函数的词法环境,而返回的函数又被其他生命周期东西所持有,导致外部函数虽然执行完了,但内存却无法被回收

所以,返回的函数,它的生命周期应尽量不宜过长,方便该闭包能够及时被回收

正常来说,闭包并不是内存泄漏,因为这种持有外部函数词法环境本就是闭包的特性,就是为了让这块内存不被回收,因为可能在未来还需要用到,但这无疑会造成内存的消耗,所以,不宜烂用就是了

4. 遗漏的 DOM 元素
DOM 元素的生命周期正常是取决于是否挂载在 DOM 树上,当从 DOM 树上移除时,也就可以被销毁回收了

但如果某个 DOM 元素,在 js 中也持有它的引用时,那么它的生命周期就由 js 和是否在 DOM 树上两者决定了,记得移除时,两个地方都需要去清理才能正常回收它

5. 网络回调
某些场景中,在某个页面发起网络请求,并注册一个回调,且回调函数内持有该页面某些内容,那么,当该页面销毁时,应该注销网络的回调,否则,因为网络持有页面部分内容,也会导致页面部分内容无法被回收

你可能感兴趣的:(js)