使用 Chrome Dev tools 分析应用的内存泄漏问题

Catching memory leaks with Chrome DevTools

当分配的内存没有返回给操作系统或内存池时,我们将其称为内存泄漏。 在这种情况下,内存未被任何应用程序使用,并且被不必要地占用。 这会导致低性能、高延迟和频繁崩溃。

Understanding memory leaks

如果您熟悉 C 等低级语言,您一定使用过 malloc() 和 free()。 相比之下,JavaScript 在创建对象时自动分配内存,并在不再使用时释放它。

好吧,因为它是自动管理的,所以我们作为开发人员总是有一个错误的印象,即我们不需要担心浏览器中的内存管理。 如果一个站点使用越来越多的内存,这意味着没有人收集它并且存在内存泄漏。

Garbage collectors

如果垃圾收集器 (GC) 是完美的,那么内存泄漏就不是问题。 问题是他们的算法不够聪明,无法检测内存泄漏。 因此,需要人工干预。

垃圾收集器执行查找程序不再使用的内存并将其释放回操作系统以供将来重新分配的过程。 该方法有效,但仍然会发生内存泄漏。 该方法无法检测每个泄漏,例如泄漏的引用。

Why is there a memory leak?

下列是几种常见的内存泄漏类型。

Accidental global variables

function getWork() {
  this.work = “I am Memory leak”;
}
// The this here refers to window object and hence this variable will be created in the window.
getWork();

这里的 this 指的是 window 对象,因此这个变量将在 window 中创建。

由于全局变量不是由 GC 收集的,如果此字符串变得太大,可能会导致内存泄漏。 意外全局变量的一个类似示例是在不使用 let 和 var 关键字的情况下声明变量。

Detached DOM nodes

分离 DOM 节点是一个关键问题。 由于全局引用,分离的节点仍然存在于内存中。

var node = document.createElement('a’);
node.id = 'id1';
document.body.appendChild(node);
var main = {
   Id: document.getElementById('id1’)
}
function removeElement(){
   document.body.removeChild(document.getElementById('id1’));
}
removeElement();

在上面的例子中,removeChild 函数从树中移除了 DOM 节点,但是全局主对象中的引用 Id 仍然保留在内存中并且没有被垃圾收集。

闭包

闭包为内部函数维护外部函数变量的范围,即使在外部函数的范围之外。

function getScore(x) {
   function score(y) {
      return x + y;
    }
   return score;
}
var initial = getScore(2);
var final = initial(3);

这里的函数score,也就是内部函数,有一个全局引用,叫做initial。 这个初始引用永远不会被垃圾收集。

Tools to identify memory leaks

意外的全局变量 内存泄漏可以通过分析轻松检测到。 我们举一个代码片段的例子,它会因为全局变量而导致内存泄漏。 例子:

var x = []
var bool = false;
function grow(){
  x.push(new Array(100000).join('a’));
  if(bool){
    setTimeout(grow, 1000);
  }
}
function start(){
  grow();
  bool = true;
}
function stop(){
  bool = false;
}

到 Chrome 开发者工具里,打开 Profiles 标签页:

选择 Take Heap Snapshot.

在这里,window 对象的黄色实际上描绘了从 JS 代码中直接引用的节点。 我们需要修复这里的代码,以便我们可以摆脱黄色标记。

此处的选项是在函数内将数组设为局部,以便垃圾收集器可以收集它或显式删除全局变量。 您可以找到更正后的代码:

var bool = false;
function grow(){
  var x = [];
  x.push(new Array(100000).join('a’));

  if(bool){
   setTimeout(grow, 1000);
  }
}
function start(){
  grow();
  bool = true;
}
function stop(){
  bool = false;
}

Allocation profiler

Allocation Timeline 是另一个工具,可以帮助您跟踪 JS 堆中的内存泄漏。 要记录时间线,请转到您的 profile 面板,然后单击上面给出的相同代码的开始。

当我们单击如图所示的开始按钮并使用分配分析器进行配置时,我们可以看到它生成了如图所示的蓝线。

蓝条代表新的内存分配,这可能是内存泄漏。 您可以通过缩放这些蓝色条中的任何一个来查看详细信息。 此处的详细信息表示被推入数组且从不进行垃圾回收的长字符串。

(0)

相关推荐

  • JavaScript 之 作用域

    学习目标:能够说出Javascript的两种作用域 能够区分全局变量和局部变量 能够说出如何在作用域链中查找变量的值 1.作用域 <script> //1.javaScript作用域:就是 ...

  • javascript中的闭包这一篇就够了

    前端技术优选 今天 以下文章来源于程序员成长指北 ,作者koala 程序员成长指北专注 Node.js 技术栈分享,从 前端 到 Node.js 再到 后端数据库,祝您成为优秀的高级 Node.js ...

  • jQuery闭包理解

    参考https://tylermcginnis.com/async-javascript-from-callbacks-to-promises-to-async-await/ 闭包定义-是指有权访问另 ...

  • 一个用于 Angular 开发的 Chrome 扩展 - Angular Dev Tools

    该扩展安装到 Chrome 浏览器之后,Chrome 开发者工具会多出一个标签页: 可以在 Component 面板里查看 Component 的属性,或者直接对其修改: 在 Component 面板 ...

  • 使用 Chrome 开发者工具分析内存问题

    DevTools 显示了按功能划分的内存分配细目. 默认视图是 Heavy (Bottom Up),它在顶部显示分配最多内存的函数. Fix memory problems 内存泄漏很容易定义. 如果 ...

  • JVisualVM简介与内存泄漏实战分析

    一.JVisualVM能做什么       VisualVM 是Netbeans的profile子项目,已在JDK6.0 update 7 中自带(java启动时不需要特定参数,监控工具在bin/jv ...

  • 分析赛博朋克gtx1060内存能不能玩详细介绍

    赛博朋克2077gtx1060能玩吗?赛博朋克2077游戏是目前非常火热的角色扮演游戏,使用gtx1060的小伙伴不清楚自己的设备是不是能玩这款游戏,下面小编为大家带来赛博朋克gtx1060内存能不能 ...

  • [Spring Boot 系列教程] Dev Tools

    [Spring Boot 系列教程] 目录 源码(demo03) 在上一篇文章中,介绍了 Spring Boot 的项目结构及自动构建机制,在本文中,将介绍 Spring Boot 开发者工具. 在 ...

  • 深入分析 ThreadLocal 内存泄漏问题

    总结:由于ThreadLocalMap的生命周期跟Thread一样长,如果没有手动删除对应key就会导致内存泄漏,我觉得是这种数据结构导致,会产生内存溢出的问题Java为了最小化减少内存泄露的可能性和 ...

  • 一文带你了解如何排查内存泄漏导致的页面卡顿现象

    "脚本之家 ",与百万开发者在一起 作者 | 零一0101 来源 | 前端印象(ID: Lpyexplore) 不知道在座的各位有没有被问到过这样一个问题:如果页面卡顿,你觉得可能 ...

  • 一次解决Linux内核内存泄漏实战全过程

    2020 年转眼间白驹过隙般飞奔而去,在岁末年初的当口,笔者在回顾这一年程序员世界的大事件后,突然发觉如何避免程序员面向监狱编程是个特别值得一谈的话题. 什么是内存泄漏 程序向系统申请内存,使用完不需 ...

  • Android开发常见内存泄漏和相应的对策(二)

    原创 looshen09 印象Android 2018-08-05三.定位分析内存问题1.log分析在Android系统中,GC有以下三种类型:①kGcCauseForAlloc:在分配内存时发现内存 ...