常见的JavaScript内存泄露与优化

内存泄露的含义

内存泄漏其意是一块被分配的内存既不能使用,又不能被回收,直到浏览器结束,这样的状态则是内存泄露。现在比较高级的计算机语言都有了自动分配内存和回收的机制,比如说java、c#、JavaScript等所谓的垃圾回收机制。这样大大降低了程序员的开发难度。但是比较早期的c、c++语言也是不具备的垃圾回收机制的。

char * buffer;

buffer = (char*) malloc(42);

// Do something with buffer

free(buffer);

上面是 C 语言代码,malloc方法用来申请内存,使用完毕之后,必须自己用free方法释放内存。所以拥有了垃圾回收机制之后,解放了程序员的双手,不需要时刻关注内存的问题。但是浏览器也是存在缺陷的,并不是所有场景,浏览器都会帮我们把泄露的内存回收,所以以下内容简单列举出几种JavaScript常见的产生内存泄漏的例子及处理的方法。

如何知道浏览器内存是否泄露

chrome查看内存泄漏教程。点击此链接即可查看详细教程。本人对睿江云的ecp首页做了测试,存在大量的内存泄露,所以导致首页加载时间长,下面是对睿江云首页的测试,蓝色折现逐渐上升,说明存在内存泄漏。如果是一条平缓直线,则说明没有内存泄漏。

睿江云首页测试

内存泄漏的例子和处理方法

第一个例子:
当页面中元素被移除或替换时,若元素绑定的时间仍没被移除,在IE中不会做出恰当处理,此时要先手工移除事件,不然会存在内存泄露。
在这里插入图片描述
存在泄露的代码
代码应为:
在这里插入图片描述
或采用事件委托:
在这里插入图片描述
第二个例子:
在这里插入图片描述
这段代码把一个匿名函数注册为一个DOM结点的click事件处理函数,函数内引用了一个DOM对象elem,就形成了闭包。这就会产生一个循环引用,即:DOM->闭包->DOM->闭包…DOM对象在闭包释放之前不会被释放;而闭包作为DOM对象的事件处理函数存在,所以在DOM对象释放前闭包不会释放,即使DOM对象在DOM tree中删除,由于这个循环引用的存在,DOM对象和闭包都不会被释放。可以用下面的方法可以避免这种内存泄露。
在这里插入图片描述
第三个例子:
在这里插入图片描述
闭包非常容易构成循环引用。如果一个构成闭包的函数对象被指定给,比如一个 DOM 节点的事件处理器,而对该节点的引用又被指定给函数对象作用域中的一个活动(或可变)对象,那么就存在一个循环引用。形成这样一个循环引用是轻而易举的,而且稍微浏览一下包含类似循环引用代码的网站(通常会出现在网站的每个页面中),就会消耗大量(甚至全部)系统内存。 解决之道,将事件处理函数定义在外部,解除闭包。
在这里插入图片描述
或者在click事件处理函数程序内部把没有用的属性删除
在这里插入图片描述
第四个例子:
在这里插入图片描述
执行这段代码之后b.x的值依然是1.由于已经删除的属性引用依然存在,因此在JavaScript的某些实现中,可能因为这种不严谨的代码而造成内存泄露。所以在销毁对象的时候,要遍历属性中属性,依次删除。

第五个例子:
在这里插入图片描述
上面的代码在ie系列中会导致内存泄露。s本身是一个string而非object,它没有length属性,所以当访问length时,JS引擎会自动创建一个临时String对象封装s,而这个对象一定会泄露。这个bug匪夷所思,所幸解决起来相当容易,记得所有值类型做.运算之前先显式转换一下:
在这里插入图片描述
第六个例子,使用时间委托减少内存泄漏:
在这里插入图片描述
上面的例子是我们平时对做监听的惯性思维,但是这种方法对性能的消耗比较大,存在内存泄漏。所以我们可以用事件委托来处理这种场景。下面是采用事件委托的代码。
在这里插入图片描述
本文主要介绍了JavaScript

几种内存泄露的场景及处理方法。

了解JavaScript的内存泄露场景,

可以让我们写出科学的Java程序。

注:本篇参考《JavaScript高级程序设计》和网上的博客。如有侵犯,私聊删除,联系邮箱[email protected]

下期预告:常见的前端跨域解决方案
在这里插入图片描述睿江云计算官网:http://www.eflycloud.com/home?from=RJ_0024

猜你喜欢

转载自blog.csdn.net/RJ0024/article/details/89850066