如何监控 JavaScript Web 应用内存及内存问题初解

Performance工具介绍

GC的目的是为零实现内存空间的良性循环

通过使用Performance 可以对当前程序运行时内存变化进行监控,这样就可以在程序出现问题时想办法定位到当前出现问题的代码块。

Performance使用步骤:

  1. 打开浏览器输入目标网址;
  2. 打开开发人员选项,选择性能;
  3. 开启录制功能,访问具体页面;
  4. 执行用户行为,一段时间后停止录制;
  5. 分析页面中的记录的内存信息。

内存问题的体现

  • 页面出现延迟加载或经常性暂停--------频繁的GC回收(有一些代码瞬间让内存爆掉了就触发频繁的GC)
  • 页面持续性出现糟糕性能表现-----------内存膨胀(当前页面为了达到最佳使用速度,去申请更大的内存空间,超出了当前设备可提供的最大内存)
  • 页面的性能随时间延长越来越差--------内存泄漏(随时间增长,内存空间越来越少)

如何判断当前内存问题属于哪种

  • 怎么判断内存泄露

内存使用持续升高没有降低

  • 怎么判断内存膨胀

内存膨胀指的是程序达到期望的效果所需很大的内存空间,内存膨胀很大可能是硬件不支持所导致的,要想判断是程序的问题还是硬件设备的问题,就应该在多个设备上多做些测试,如果在设备上程序都出现了问题,那就表明是程序出了内存膨胀的问题。

  • 怎么判断存在频繁的垃圾回收

通过内存变化图进行分析

监控内存的几种方式

  • 浏览器任务管理器:会将程序的内存变化表现出来

  • Timeline 时序图记录:把程序使用过程中的内存走势以时间点的方式呈现出来

  • 堆快照查找分离DOM:能够有针对性的查找当前界面对象中是否存在分离的DOM,分离DOM的存在就表示着一种内存泄露。

  • 借助不同工具查看内存走势图,进行时间段的分析以判断是否存在频繁的垃圾回收

任务管理器监控内存

1.如何调出浏览器任务管理器?

通过浏览器快捷键 shift + esc 调出浏览器任务管理器,在任务管理器里右键选中 JavaScript 内存以展示内存占用情况

2.如何使用浏览器任务管理器进行内存分析?

首先我们要明白在浏览器任务管理器中显示的内存和 JavaScript 内存的区别

  • 内存为原生内存即dom节点所占据的内存频繁的dom操作会使原生内存不断增大。
  • JavaScript 内存表示的是 js 里的堆,即界面中所有可达对象正在使用的内存大小,JavaScript 内存的值若一直在增大,那就意味着当前页面中在不断的创建对象要么是现有对象正在不断增长所占内存空间。

注意:默认情况下 JavaScript 内存 这一列不显示,右击选择当前页面脚本,显示即可。
如何监控 JavaScript Web 应用内存及内存问题初解_第1张图片

3.总结

浏览器任务管理器只能帮助我们发现当前界面是否存在内存问题,但是如果我们想定位问题就不太够用了。

Timeline 记录内存(performance)

通过时间线记录内存变化的方式来演示如何更精确的定位当前内存问题跟哪块代码相关或在什么时间节点发生的。

蓝色 - JS堆

红色 - 文档

绿色 - 节点

黄色 - 监听器

深紫 - GPU

我们只需要查看 JS 堆,记得勾选内存才能看到这些东西。

JS 堆线条走势是有涨有跌,那就表明内存使用是正常的。

通过拖动 performance 自带的界面时序并根据 timeline 内存时间线就能够定位内存问题出现的界面行为。

堆快照查找分离DOM

在程序运行时进行内存监控。performance 旁边的内存按钮。

  • 堆快照的工作原理

首先找到当前 JS 堆,然后进行照片留存,这样我们就能够看到它的所有信息。它更像是专门针对分离 Dom 的查找行为。

  • 什么是垃圾 Dom ?什么是分离 Dom?
  1. dom 本应该都是存在于一个存活的 dom 树上的。
  2. 如果 dom 脱离了 dom 树 且 js 对它没有任何的引用,那么这个 dom 就成为了垃圾对象。
  3. 如果 dom 只是脱离了 dom 树,js 对它还存在引用,这种 dom 就是分离 dom,分离 dom 在界面上是看不见的,但在内存里确是占据着空间的,这就属于内存泄漏。

那么我们就可以通过堆快照的方式来找到分离 Dom,我们找到了就可以到相应代码位置进行清除,这样就可以让内存得到释放,程序执行更迅速。

let tmpEle;
function fn(){
    var ul = document.createElement('ul');
    for(let i = 0;i<10;i++){
        let li = document.createElement('li');
        ul.appendChild(li);
    }
    tmpEle = ul;    
    // tmpEle = null;//清除分离dom
};
document.getElementById("btn").addEventListener('click',fn);

你可能感兴趣的:(Es6新特性,TS,JavaScript性能优化,javascript内存问题,监控内存,堆快照,分离dom,内存泄漏)