Chrome开发者工具详解(4)-Profiles面板

Chrome开发者工具详解(4)-Profiles面板

如果上篇中的Timeline面板所提供的信息不能满足你的要求,你可以使用Profiles面板,利用这个面板你可以追踪网页程序的内存泄漏问题,进一步提升程序的JavaScript执行性能

概述

当前使用的Chrome最新版为54.0.2840.71,这个版本的Profiles面板比之前提供的功能更多也更强大,下面是该面板所包含的功能点:

  • Record JavaScript CPU Profile 用于分析网页上的JavaScript函数在执行过程中的CPU消耗信息。
  • Take Heap Snapshot 创建堆快照用来显示网页上的JS对象和相关的DOM节点的内存分布情况。
  • Record Allocation Timeline 从整个Heap角度记录内存的分配信息的时间轴信息,利用这个可以实现隔离内存泄漏问题。
  • Record Allocation Profile 从JS函数角度记录内存的分配信息。

profile-panel.png

Record JavaScript CPU Profile简介

通过选择Record JavaScript CPU Profile,然后点击Start,结合你所要分析的具体场景,你可以重新加载网页,或者在网页上进行交互,甚至什么都不操作。最后点击Stop,完成记录操作。

有三种不同的视图可供选择:

  • Chart 按时间先后顺序显示的火焰图。

profile-1-chart.png

  • Heavy(Bottom Up) (自底向上)根据对性能的消耗影响列出所有的函数,并可以查看该函数的调用路径。

profile-1-heavy.png

  • Tree(Top Down) (自顶向下) 从调用栈的顶端(最初调用的位置)开始,显示调用结构的总体的树状图情况。

profile-1-tree.png

我们以Chart视图为例分析一下JS的执行的性能情况:

profile-js-cpu-chart.png

该视图会以时间顺序展示CPU的性能情况,视图主要分成两块:

  • Overview 整个录制结果的鸟瞰图(概览),柱形条的高度对应了调用堆栈的深度,也就是说柱形条高度越高,调用堆栈的深度越深。
  • Call Stacks 在录制过程中被调用的函数的深入分析视图(调用堆栈),横轴表示时间,纵轴表示调用栈,自上而下的表示函数的调用情况。也就是说上面的函数调用在它下面的函数。

视图中的函数颜色不同于其它的面板,这里面的函数颜色标记是随机显示的。然而相同的函数调用颜色标记是相同的。

其中纵轴表示的函数调用堆栈高度仅仅函数的调用嵌套层次比较深,不表示其重要性很高,但是横轴上一个很宽的柱形条则意味着函数的调用需要一个很长的时间去完成,那么你就考虑去做一些优化操作,具体可以参见网络性能优化方案及里面的相关参考文档。

将鼠标移到Call Stacks中的函数上可以显示函数的名称和时间相关的数据,会提供如下信息:

  • Name 函数名称
  • Self time 函数的本次调用运行的时间,仅仅包含该函数本身的运行时间,不包含它所调用的子函数的时间。
  • Total time 函数的本次调用运行的总时间,包含它所调用的子函数的运行时间。
  • URL 函数定义在文件中所在的位置,其格式为file.js:100,表示函数在file.js文件中的第100行。
  • Aggregated self time 在这次的录制过程中函数调用运行的总时间,不包含它所调用的子函数的时间。
  • Aggregated total time 在这次的录制过程中所有的函数调用运行的总时间,包含它所调用的子函数的时间。
  • Not optimized 如果优化器检测到该函数有潜在的优化空间,那么该函数会被列在这里。

Take Heap Snapshot简介

通过创建堆快照可以查看创建快照时网页上的JS对象和DOM节点的内存分布情况。利用该工具你可以创建JS的堆快照、内存分析图、对比堆快照以及定位内存泄漏问题。选中Take Heap Snapshot,点击Take Snapshot按钮即可获取快照,在每一次获取快照前都会自动执行垃圾回收操作。

快照最初会存储在渲染进程的内存之中,当我们点击创建快照按钮来查看时才会被传输到DevTools中,当快照被加载到DevTools里面并经过解析之后,在快照标题下方的文字显示是数字就是可访问到的JS对象总的大小。

profile-2-overview.png

堆快照提供了不同的视角来进行查看:

  • Summary 该视图按照构造函数进行分组,用它可以捕获对象和它们使用的内存情况,对于跟踪定位DOM节点的内存泄漏特别有用。
  • Comparison 对比两个快照的差别,用它可以对比某个操作前后的内存快照。分析操作前后的内存释放情况以及它的引用计数,便于你确认内存是否存在泄漏以及造成的原因。
  • Containment 该视图可以探测堆的具体内容,它提供了一个更适合的视图来查看对象结构,有助于分析对象的引用情况,使用它可以分析闭包和进行更深层次的对象分析。
  • Statistics 统计视图。

Summary视图

该视图会显示所有的对象信息,点击其中的一个对象进行展开可查看更详细的实例信息。鼠标移动到某个对象上会显示该对象实例的详情信息。

profile-2-summary.png

图中的各列的具体含义如下:

  • Constructor 显示所有的构造函数,点击每一个构造函数可以查看由该构造函数创建的所有对象。
  • Distance 显示通过最短的节点路径到根节点的距离。
  • Objects Count 显示对象的个数和百分比。
  • Shallow size 显示由特定的构造函数创建的所有对象的本身的内存总数。
  • Retained size 显示由该对象及其它所引用的对象的总的内存总数。

Shallow sizeRetained size的区别?Shallow size是对象本身占用内存的大小,不包含它所引用的对象。Retained size是该对象本身的Shallow size,加上能从该对象直接或者间接访问到对象的Shallow size之和。也就是说Retained size是该对象被GC之后所能回收到内存的总和。

在展开构造函数,则会列出该函数相关的所有对象实例,可以查看该对象的Shallow size和Retained size,在@符号后面的数字是该对象的唯一标识ID。

其中黄色的对象表示在它被某个JS所引用,而红色的对象表示由黄色背景色引用被分离开出的节点。

profile-2-summary2.png

这些构造函数都代表什么含义呢?

  • (global property) 全局对象(比如window)和通过它引用的对象之间的中间对象,如果一个对象是由Person构造函数生成并被全局对象所引用,那么它们的引用路径关系就像这样[global] > (global property) > Person。这跟常规的对象之间直接引用相比,采用中间对象主要是考虑性能的原因。全局对象的改变是很频繁的,而非全局变量的属性访问最优化方案对全局变量是不适用的。
  • (roots) 它们可以是由引擎自己的目标创建的一些引用,这个引擎可以缓存引用的对象,但所有的这些引用都是弱引用,它们不会阻止引用对象被回收。
  • (closure) 一些函数闭包中的一组对象的引用。
  • (array, string, number, regexp) 一系属性引用了数组(Array),字符串(String),数字(Number)或正则表达式的对象类型。
  • HTMLDivElement, HTMLAnchorElement, DocumentFragment等 你的代码中对元素(elements)的引用或者指定的document对象的引用。

Comparison视图

通过比较多个快照之间的差异来找出内存泄露的对象,为了验证某个程序的操作不会引起内存泄露(通常会执行一个操作后再执行一个对应的相反操作,比如打开一个文档后再关闭它,应该是没有产生内存泄露问题的),你可以执行如下步骤:

  1. 在执行一个操作之前拍一个快照。
  2. 执行一个操作,通过你认为可能会引起内存泄露的一次页面交互操作。
  3. 执行一个相反的操作。
  4. 拍第二个快照,切换到Comparison视图,并与第一个快照进行对比。

profile-2-comparison.png

切换到Comparison视图之后,就可以看到两个不同的快照之间的差别。

Containment视图

该视图本质上就是应用程序的对象结构的“鸟瞰图”,允许你去深入分析函数的闭包,了解应用程序底层的内存使用情况。

这个视图提供了多个入口:

  • DOMWindow objects DOMWindow对象,即JS代码全局对象。
  • Native objects 浏览器原生对象,比如DOM节点,CSS规则。

profile-2-containment.png

闭包小建议: 在快照的分析中命名函数的闭包相比匿名函数的闭包更容易区分。

Google上提供的例子和图如下:

function createLargeClosure() {var largeStr = new Array(1000000).join('x');var lC = function() { // 匿名函数return largeStr;};return lC;
}
function createLargeClosure() {var largeStr = new Array(1000000).join('x');var lC = function lC() { // 命名函数return largeStr;};return lC;
}

domleaks.png

Statistics视图

该视图是堆快照的总的分布统计情况,这个直接上图就可以了:

profile-2-statistics.png

内存泄露示例

还是把Google提供的内存泄露的小例子贴出来:

DOM内存泄露可能比你想象的要大,考虑一下下面的例子-什么时候#tree节点被释放掉?

  var select = document.querySelector;var treeRef = select("#tree");var leafRef = select("#leaf");var body = select("body");body.removeChild(treeRef);//由于treeRef #tree不能被释放treeRef = null;//由于leafRef的间接引用 #tree还是不能被释放leafRef = null;//现在没有被引用,#tree这个时候才可以被释放了

profile-treegc.png

#leaf节点保持着对它的父节点(parentNode)的引用,这样一直递归引用了#tree节点,所以只有当leafRef被设置成null后,#tree下面的整个树节点才有可能被垃圾回收器回收。

Record Allocation Timeline简介

该工具是可以帮助你追踪JS堆里面的内存泄漏的另一大利器。

选中Record Allocation Timeline按钮,点击Start按钮之后,执行你认为可能会引起内存泄漏的操作,操作之后点击左上角的停止按钮即可。你可以在蓝色竖线上通过缩放来过滤构造器窗格来仅仅显示在指定的时间帧内的被分配的对象。

录制过程中,在时间线上会出现一些蓝色竖条,这些蓝色竖条代表一个新的内存分配,这个新的内存分配都可以会有潜在的内存泄露问题。

profile-3-summary.png

通过展开对象并点击它的值则可以在Object窗格中查看更多新分配的对象细节。

profile-3-summary-object.png

Record Allocation Profile简介

从JS函数角度记录并查看内存的分配信息。点击Start按钮,执行你想要去深入分析的页面操作,当你完成你的操作后点击Stop按钮。然后会显示一个按JS函数进行内存分配的分解图,默认的视图是Heavy (Bottom Up),该视图会把最消耗内存的函数显示在最顶端。

下图是切换到Chart视图时具体的界面,点击任意函数跳转到Sources面板可以查看具体的函数信息。

profile-4-chart.png

参考文档

  • Uncovering DOM Leaks
  • Shallow and retained sizes

个人博客

我的个人博客

转载于:https://www.cnblogs.com/charliechu/p/6003713.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/254103.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

halcon通过点拟合圆形,鼠标选点

原图 源码 read_image (Image, 0.bmp) dev_clear_window () dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle) dev_display (Image)binary_threshold (Image, Region, max_separability, dark, UsedThreshold) connection (Region, ConnectedRegions) select_s…

LINUX多播编程

一.单播,广播和多播 1.单播用于两个主机之间的端对端通信,广播用于一个主机对整个局域网上所有主机上的数据通信。单播和广播是两个极端,要么对一个主机进行通信,要么对整个局域网上的主机进行通信。实际情况下,经常需…

cas单点登录搭建

Cas Server下载:http://developer.jasig.org/cas/ Cas Client下载:http://developer.jasig.org/cas-clients/ 测试环境: jdk:java version "1.8.0_60" tomcat:apache-tomcat-7.0.65 mysql:mysql5…

689D Magic Odd Square 奇数幻方

1 奇数阶幻方构造法 (1) 将1放在第一行中间一列; (2) 从2开始直到nn止各数依次按下列规则存放:按 45方向行走,向右上,即每一个数存放的行比前一个数的行数减1,列数加1 (3) 如果行列范围超出矩阵范围,则回绕。例如1在第…

Java单例的常见形式

2019独角兽企业重金招聘Python工程师标准>>> Java单例的常见形式 本文目的:总结Java中的单例模式 本文定位:学习笔记 学习过程记录,加深理解,便于回顾。也希望能给学习的同学一些灵感 一、非延迟加载单例类 public cla…

U-Boot启动过程完全分析

1.1 U-Boot 工作过程 U-Boot启动内核的过程可以分为两个阶段,两个阶段的功能如下: (1)第一阶段的功能 硬件设备初始化 加载U-Boot第二阶段代码到RAM空间 设置好栈 跳转到第二阶段代码入口 (2&#x…

CJOJ 2171 火车站开饭店(树型动态规划)

CJOJ 2171 火车站开饭店(树型动态规划) Description 政府邀请了你在火车站开饭店,但不允许同时在两个相连的火车站开。任意两个火车站有且只有一条路径,每个火车站最多有 50 个和它相连接的火车站。 告诉你每个火车站的利润&#…

各视频、各音频之间格式任意玩弄(图文详解)

写在前面说的话 在这里,记录下来,是为了方便以后偶尔所制作所需和你们前来的浏览学习。 学会,玩弄一些视频和音频的软件,只有好处没有害处。同时,也不需很多时间,练练手罢了。也是方便自己所用吧&#xff0…

oracle 如何查看日志?

2019独角兽企业重金招聘Python工程师标准>>> Oracle日志查看一.Oracle日志的路径:登录:sqlplus "/as sysdba"查看路径:SQL> select * from v$logfile;SQL> select * from v$logfile;(#日志文件路径)二…

回归_英国酒精和香烟关系

sklearn实战-乳腺癌细胞数据挖掘(博客主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId1005269003&utm_campaigncommission&utm_sourcecp-400000000398149&utm_mediumshare 数据统计分析联系:QQ:&a…

【转】如何用Maven创建web项目(具体步骤)

使用eclipse插件创建一个web project 首先创建一个Maven的Project如下图 我们勾选上Create a simple project (不使用骨架) 这里的Packing 选择 war的形式 由于packing是war包,那么下面也就多出了webapp的目录 由于我们的项目要使用eclipse发…

可能是目前最详细的Redis内存模型及应用解读

Redis是目前最火爆的内存数据库之一,通过在内存中读写数据,大大提高了读写速度,可以说Redis是实现网站高并发不可或缺的一部分。 我们使用Redis时,会接触Redis的5种对象类型:字符串、哈希、列表、集合、有序集合。丰富…

POJ 1696 Space Ant 极角排序(叉积的应用)

题目大意:给出n个点的编号和坐标,按逆时针方向连接着n个点,按连接的先后顺序输出每个点的编号。 题目思路:Cross(a,b)表示a,b的叉积,若小于0:a在b的逆时针方向,若大于0a在…

SuperMap iDesktop之导入数据

SuperMap作为一个平台软件有自己的数据格式,现要将ESRI的SHP数据导入到SuperMap的udb数据库中,可以完成导入,但也不得不说几点问题。 下面是ArcGIS中批量导入SHP的操作界面。 比较分析 (1)界面简洁性 明显ArcGIS要简洁…

MyBatis 实践 -配置

MyBatis 实践标签: Java与存储 Configuration mybatis-configuration.xml是MyBatis的全局配置文件(文件名称随意),其配置内容和顺序例如以下: properties : 属性(文件)载入/配置settings : 全局配置參数typeAliases : 定义类型别名typeHandlers : 类型处理器objectF…

DM365视频处理流程/DM368 NAND Flash启动揭秘

DM365的视频处理涉及到三个相关处理器,分别是视频采集芯片、ARM处理器和视频图像协处理器(VICP),整个处理流程由ARM核协调。视频处理主要涉及三个处理流程,分别是视频采集、视频编码和对编码后的视频的处理&#xff0c…

系统的Drawable(四)-LayerListDrawable

系统的Drawable(四)-LayerListDrawable 学习自 https://blog.csdn.net/u014695188/article/details/52815444 LayerListDrawable 漫谈 使用layer-list可以将多个drawable按照顺序层叠在一起显示,默认情况下,所有的item中的drawable都会自动根据它附上vie…

图像处理:镜头频率(衍射极限) 和 相机采样:显微镜的采样定理

采样定理大家都知道,相信不用多说。 我自己写下来给自己看。 下面,我总结 大家平时照相的镜头或者显微镜的物镜的情况下: 采样频率是指图像在数字化的时候的过程,实际上就是我们相机感光元件CCD或者CMOS的一个个小像元把模拟的连续…

像素越多越好?像元的面积越小越好?为何底大一级压死人?

像素越多越好?像素点的面积越小越好?为何底大一级压死人? 像素是:图像最小单元的数量,例如6000*4000,像素数量就是24*10^6。 像素太少当然图像就看不见了,看不清晰了。 但是现在几乎所有手机和相…

DM6446开发攻略:V4L2视频驱动和应用分析

针对DAVINCI DM6446平台,网络上也有很多网友写了V4L2的驱动,但只是解析Montavistalinux-2.6.10 V4L2的原理、结构和函数,深度不够。本文决定把Montavista 的Linux-2.6.18 V4L2好好分析一下,顺便讲解在产品中的应用,满足…