内存泄漏

Q: 什么是内存泄露?

A:已经不再使用的内存未能被程序释放,叫内存泄露(memory leak)。

Q: 什么情况下出现内存泄漏?

首先了解一下【垃圾回收】:垃圾回收(英语:Garbage Collection,缩写为GC)在计算器科学中是一种自动的存储器管理机制。当一个计算机上的动态存储器不再需要时,就应该予以释放,以让出存储器,这种存储器资源管理,称为垃圾回收。

A: 当一块内存不再用到,但是垃圾回收机制又无法释放这块内存的时候,就导致内存泄漏。

===========================================================================

出现内存泄露的的几种常见情况:

一、全局变量

由全局变量在程序终止前不会被垃圾回收,而JavaScript对未声明变量的处理方式是在全局对象上创建该变量的引用。浏览器中,全局即window对象,在关闭窗口或刷新前不会释放。

  全局变量的情况:

  1、未声明变量: a = 1

  2、直接调用内含this的构建函数,this会指向window,而this扩展的属性与方法,会绑定到window上

二、闭包也会造成内存泄漏 (先了解下【闭包】:一个函数与它的作用域链构成闭包。)

闭包内的函数内部调用了作用域链中的变量,会新分配内存来存储这些变量,特别是柯里化最容易造成这种问题。

三、setinterval

四、事件监听(EventListener):GC不会对事件监听主动回收,换句话说需要开发者主动处理移除

    补充:使用Node.removeChild(element)ChildNode.remove()并不会直接释放对应的event listener,但是会被gc。如果该dom对象在js中再无其他引用,与之绑定的event listener就会在合理的时机被gc。

  如果被remove的dom对象没有其他引用,你并不需要手动解绑事件。

  1. 也正是因为dom的删除,不会直接删掉对应的event listener这一特性,才会因为部分早期版本的浏览器(特别是IE)中gc算法的不完善,导致javascript的Memory Leak

  2. jQuery中的remove方法,会在移除dom元素的同时,调用一个内部函数cleanData将所有子节点及相关的event listener全部移除

 

===============

PS: js回收机制分为两种:“标记清除”&“引用计数”,主流新生代浏览器都是“标记清除”法,只有老款IE(ie8及以下)用的是“引用计数”法,因为“引用计数法”在变量循环调用时会造成内存泄漏,基本被后续浏览器抛弃。

 

posted @ 2019-08-23 16:08  刘金宇  阅读(160)  评论(0编辑  收藏  举报