阅读 439

javascript内存泄漏与优化

这是我参与8月更文挑战的第26天,活动详情查看:8月更文挑战

内存泄漏与优化

  • 平常用 JavaScript 开发代码,内存的泄漏和优化是应该经常留意的。内存泄漏是指 JavaScript 中,已经分配堆内存地址的对象由于长时间未释放或者无法释放,造成了长期占用内存,使内存浪费,最终会导致运行的应用响应速度变慢以及最终崩溃的情况。这种就是内存泄漏,你应该在日常开发和使用浏览器过程中也遇到过,那么我们来回顾一下内存泄漏的场景:

  • 过多的缓存未释放;

  • 闭包太多未释放;

  • 定时器或者回调太多未释放;

  • 太多无效的 DOM 未释放;

  • 全局变量太多未被发现。

我大概总结了这几种场景,这些现象会在开发或者使用中造成内存泄漏,以至于你的浏览器卡顿、不响应、页面打不开等问题产生。那么这些问题该怎么优化呢?我们来看下这些场景都需要注意点什么。

  1. 减少不必要的全局变量,使用严格模式避免意外创建全局变量。例如:
function foo() {
    // 全局变量=> window.bar
    this.bar = '默认this指向全局';
    // 没有声明变量,实际上是全局变量=>window.bar
    bar = '全局变量'; 
}
foo();
复制代码

这段代码中,函数内部绑定了太多的 this 变量,虽然第一眼看不出问题,但仔细一分析,其实 this 下的属性默认都是绑定到 window 上的属性,均为全局变量,这一点是非常有必要注意的。

  1. 在你使用完数据后,及时解除引用(闭包中的变量,DOM 引用,定时器清除)。例如:
var someResource = getData();
setInterval(function() {
    var node = document.getElementById('Node');
    if(node) {
        node.innerHTML = JSON.stringify(someResource));
        // 定时器也没有清除,可以清除掉
    }
    // node、someResource 存储了大量数据,无法回收
}, 1000);
复制代码

比如上面代码中就缺少清除 setInterval 的代码,类似这样的代码增多会造成内存的占用过多,这是同样也需要注意的一点。

  1. 组织好你的代码逻辑,避免死循环等造成浏览器卡顿、崩溃的问题。例如,对于一些比较占用内存的对象提供手工释放内存的方法,请看下面代码:
var leakArray = [];
exports.clear = function () {
    leakArray = [];
}
复制代码

比如这段代码提供了清空该数组内容的方法,使用完成之后可以根据合适业务时机进行操作释放。这样就能较好地避免对象数据量太大造成的内存溢出的问题。

关于内存泄漏这部分,如果你想更好地去排查以及提前避免问题的发生,最好的解决方式是通过熟练使用 Chrome 的内存剖析工具,多分析多定位 Chrome 帮你分析保留的内存快照,来查看持续占用大量内存的对象。最好在业务代码上线前做好分析和诊断,之后才能保证线上业务的质量。

文章分类
前端
文章标签