定义:程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,而引发的各种问题。
有关js中可能出现的内存泄漏情况:
意外的全局变量
在页面中全局变量的生命周期最长,除非页面关闭,否则全局变量上的内存一直都不会被回收。
当我们全局变量使用不当时,又没有及时去回收(手动赋值 null),或者拼写错误等将某个变量挂载到全局变量时,也就可能发生了内存泄漏。
遗忘的定时器未清除
定时器我们一般是使用setTimeout启动 和setInterval(set因特沃) 销毁,所以当在某个页面使用了定时器,且该页面销毁时,没有手动去释放这些定时器的话,那么这些定时器还是存活着的。
也就是说,定时器的生命周期并不挂靠在页面上,所以当在当前页面的 js 里通过定时器注册了某个回调函数,而该回调函数内又持有当前页面某个变量或某些 DOM 元素时,就会导致即使页面销毁了,由于定时器持有该页面部分引用而造成页面无法正常被回收,从而导致内存泄漏。
使用不当的闭包
函数本身会持有它定义时所在的词法环境的引用,但通常情况下,在使用完函数后,该函数所申请的内存都会被回收。
但当函数内再返回一个函数时,由于返回的函数持有外部函数的词法环境,而返回的函数又被其他生命周期东西所持有,导致外部函数虽然执行完了,但内存却无法被回收。
遗忘的DOM元素还存在引用
DOM 元素的生命周期正常是取决于是否挂载在 DOM 树上,当从 DOM 树上移除时,也就可以被销毁回收了。但如果某个 DOM 元素,在 js 中也持有它的引用时,那么它的生命周期就由 js 和是否在 DOM 树上两者决定了,要记得移除时,两个地方都需要去清理才能正常被回收。
网络回调
在某些场景中,在某个页面发起网络请求,并注册一个回调函数,且回调函数内持有该页面某些内容,那么当该页面销毁时,应该注销网络的回调,否则会因为网络持有页面部分内容,也会导致页面部分内容无法被回收。
结果:变慢,崩溃,延迟大等
简述:
总结以上可能存在的内存泄漏:
(1)全局变量没有手动null
(2)定时器没有清除
(3)闭包存在其他引用等
(4)DOM元素遗忘清除
(5)网络回调