前端面试查漏补缺--(十三) 内存泄漏

前言

本系列最开始是为了本身面试准备的.后来发现整理愈来愈多,差很少有十二万字符,最后决定仍是分享出来给你们.html

为了分享整理出来,花费了本身大量的时间,起码是只本身用的三倍时间.若是喜欢的话,欢迎收藏,关注我!谢谢!前端

文章连接

合集篇:

前端面试查漏补缺--Index篇(12万字符合集) 包含目前已写好的系列其余十几篇文章.后续新增值文章不会再在每篇添加连接,强烈建议议点赞,关注合集篇!!!!,谢谢!~vue

后续更新计划

后续还会继续添加设计模式,前端工程化,项目流程,部署,闭环,vue常考知识点 等内容.若是以为内容不错的话欢迎收藏,关注我!谢谢!node

求一分内推

目前本人也在准备跳槽,但愿各位大佬和HR小姐姐能够内推一份靠谱的武汉 前端岗位!邮箱:bupabuku@foxmail.com.谢谢啦!~git

什么是内存泄漏?

程序的运行须要内存。只要程序提出要求,操做系统或者运行时(runtime)就必须供给内存。github

对于持续运行的服务进程(daemon),必须及时释放再也不用到的内存。不然,内存占用愈来愈高,轻则影响系统性能:变慢,延迟大等 ,重则致使进程崩溃。面试

再也不用到的内存,没有及时释放,就叫作内存泄漏(memory leak)。算法

内存泄漏的识别方法

  1. 使用快捷键 F12 或者 Ctrl+Shift+J 打开 Chrome 浏览器的「开发者工具」。设计模式

  2. 选择 Performance(老版为Timeline) 选项卡,在 Capture 选项中,只勾选 Memory前端工程化

  3. 设置完成后,点击最左边的 Record 按钮,而后就能够访问网页了。

  4. 打开一个网站,例如:www.taobao.com,当网页加载完成后,点击 Stop,等待分析结果。

  5. 而后在 Chart View 上寻找内存急速降低的部分,查看对应的 Event Log,能够从中找到 GC 的日志。

具体过程以下图所示:

内存泄露的常见缘由及处理方式

常见缘由:

1. 意外的全局变量

下面代码中变量bar在foo函数内,可是bar并无声明.JS就会默认将它变为全局变量,这样在页面关闭以前都不会被释放.

function foo(){
    bar=2
    console.log('bar没有被声明!')
}
复制代码

b 没被声明,会变成一个全局变量,在页面关闭以前不会被释放.使用严格模式能够避免.

2. dom清空时,还存在引用

不少时候,为了方便存取,常常会将 DOM 结点暂时存储到数据结构中.可是在不须要该DOM节点时,忘记解除对它的引用,则会形成内存泄露.

var element = {
  shotCat: document.getElementById('shotCat')
};

document.body.removeChild(document.getElementById('shotCat'));
// 若是element没有被回收,这里移除了 shotCat 节点也是没用的,shotCat 节点依然留存在内存中.
复制代码

与此相似情景还有: DOM 节点绑定了事件, 可是在移除的时候没有解除事件绑定,那么仅仅移除 DOM 节点也是没用的

3. 定时器中的内存泄漏

var someResource = getData();
setInterval(function() {
    var node = document.getElementById('Node');
    if(node) {
        node.innerHTML = JSON.stringify(someResource));
    }
}, 1000);
复制代码

若是没有清除定时器,那么 someResource 就不会被释放,若是恰好它又占用了较大内存,就会引起性能问题. 可是 setTimeout ,它计时结束后它的回调里面引用的对象占用的内存是能够被回收的. 固然有些场景 setTimeout 的计时可能很长, 这样的状况下也是须要归入考虑的.

4. 不规范地使用闭包

例以下面的例子: 相互循环引用.这是常常容易犯的错误,而且有时也不容易发现.

function foo() { 
  var a = {}; 
  function bar() { 
    console.log(a); 
  }; 
  a.fn = bar; 
  return bar; 
};
复制代码

bar和a造成了相互循环引用.可能有人说bar里不使用console.log(a)不就没有引用了吗就不会形成内存泄露了.NONONO,bar做为一个闭包,即便它内部什么都没有,foo中的全部变量都仍是隐式地被 bar所引用。 即便bar内什么都没有仍是形成了循环引用,那真正的解决办法就是,不要将a.fn = bar.

避免策略:

  1. 减小没必要要的全局变量,或者生命周期较长的对象,及时对无用的数据进行垃圾回收(即赋值为null);
  2. 注意程序逻辑,避免“死循环”之类的 ;
  3. 避免建立过多的对象 原则:不用了的东西要记得及时归还。
  4. 减小层级过多的引用

Node中的内存泄漏

node中的内存泄露与JS中的处理方法稍有不一样,详细能够查看这篇文章,很是的详细!

感谢及参考

相关文章
相关标签/搜索