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函数角度记录内存的分配信息。
Record JavaScript CPU Profile简介
通过选择Record JavaScript CPU Profile,然后点击Start,结合你所要分析的具体场景,你可以重新加载网页,或者在网页上进行交互,甚至什么都不操作。最后点击Stop,完成记录操作。
有三种不同的视图可供选择:
- Chart 按时间先后顺序显示的火焰图。
- Heavy(Bottom Up) (自底向上)根据对性能的消耗影响列出所有的函数,并可以查看该函数的调用路径。
- Tree(Top Down) (自顶向下) 从调用栈的顶端(最初调用的位置)开始,显示调用结构的总体的树状图情况。
我们以Chart视图为例分析一下JS的执行的性能情况:
该视图会以时间顺序展示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对象总的大小。
堆快照提供了不同的视角来进行查看:
- Summary 该视图按照构造函数进行分组,用它可以捕获对象和它们使用的内存情况,对于跟踪定位DOM节点的内存泄漏特别有用。
- Comparison 对比两个快照的差别,用它可以对比某个操作前后的内存快照。分析操作前后的内存释放情况以及它的引用计数,便于你确认内存是否存在泄漏以及造成的原因。
- Containment 该视图可以探测堆的具体内容,它提供了一个更适合的视图来查看对象结构,有助于分析对象的引用情况,使用它可以分析闭包和进行更深层次的对象分析。
- Statistics 统计视图。
Summary视图
该视图会显示所有的对象信息,点击其中的一个对象进行展开可查看更详细的实例信息。鼠标移动到某个对象上会显示该对象实例的详情信息。
图中的各列的具体含义如下:
- Constructor 显示所有的构造函数,点击每一个构造函数可以查看由该构造函数创建的所有对象。
- Distance 显示通过最短的节点路径到根节点的距离。
- Objects Count 显示对象的个数和百分比。
- Shallow size 显示由特定的构造函数创建的所有对象的本身的内存总数。
- Retained size 显示由该对象及其它所引用的对象的总的内存总数。
Shallow size和Retained size的区别?Shallow size是对象本身占用内存的大小,不包含它所引用的对象。Retained size是该对象本身的Shallow size,加上能从该对象直接或者间接访问到对象的Shallow size之和。也就是说Retained size是该对象被GC之后所能回收到内存的总和。
在展开构造函数,则会列出该函数相关的所有对象实例,可以查看该对象的Shallow size和Retained size,在@符号后面的数字是该对象的唯一标识ID。
其中黄色的对象表示在它被某个JS所引用,而红色的对象表示由黄色背景色引用被分离开出的节点。
这些构造函数都代表什么含义呢?
- (global property) 全局对象(比如
window
)和通过它引用的对象之间的中间对象,如果一个对象是由Person构造函数生成并被全局对象所引用,那么它们的引用路径关系就像这样[global] > (global property) > Person。这跟常规的对象之间直接引用相比,采用中间对象主要是考虑性能的原因。全局对象的改变是很频繁的,而非全局变量的属性访问最优化方案对全局变量是不适用的。 - (roots) 它们可以是由引擎自己的目标创建的一些引用,这个引擎可以缓存引用的对象,但所有的这些引用都是弱引用,它们不会阻止引用对象被回收。
- (closure) 一些函数闭包中的一组对象的引用。
- (array, string, number, regexp) 一系属性引用了数组(Array),字符串(String),数字(Number)或正则表达式的对象类型。
- HTMLDivElement, HTMLAnchorElement, DocumentFragment等 你的代码中对元素(elements)的引用或者指定的document对象的引用。
Comparison视图
通过比较多个快照之间的差异来找出内存泄露的对象,为了验证某个程序的操作不会引起内存泄露(通常会执行一个操作后再执行一个对应的相反操作,比如打开一个文档后再关闭它,应该是没有产生内存泄露问题的),你可以执行如下步骤:
- 在执行一个操作之前拍一个快照。
- 执行一个操作,通过你认为可能会引起内存泄露的一次页面交互操作。
- 执行一个相反的操作。
- 拍第二个快照,切换到Comparison视图,并与第一个快照进行对比。
切换到Comparison视图之后,就可以看到两个不同的快照之间的差别。
Containment视图
该视图本质上就是应用程序的对象结构的“鸟瞰图”,允许你去深入分析函数的闭包,了解应用程序底层的内存使用情况。
这个视图提供了多个入口:
- DOMWindow objects DOMWindow对象,即JS代码全局对象。
- Native objects 浏览器原生对象,比如DOM节点,CSS规则。
闭包小建议: 在快照的分析中命名函数的闭包相比匿名函数的闭包更容易区分。
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;
}
Statistics视图
该视图是堆快照的总的分布统计情况,这个直接上图就可以了:
内存泄露示例
还是把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这个时候才可以被释放了
#leaf
节点保持着对它的父节点(parentNode)的引用,这样一直递归引用了#tree
节点,所以只有当leafRef
被设置成null后,#tree
下面的整个树节点才有可能被垃圾回收器回收。
Record Allocation Timeline简介
该工具是可以帮助你追踪JS堆里面的内存泄漏的另一大利器。
选中Record Allocation Timeline按钮,点击Start按钮之后,执行你认为可能会引起内存泄漏的操作,操作之后点击左上角的停止按钮即可。你可以在蓝色竖线上通过缩放来过滤构造器窗格来仅仅显示在指定的时间帧内的被分配的对象。
录制过程中,在时间线上会出现一些蓝色竖条,这些蓝色竖条代表一个新的内存分配,这个新的内存分配都可以会有潜在的内存泄露问题。
通过展开对象并点击它的值则可以在Object窗格中查看更多新分配的对象细节。
Record Allocation Profile简介
从JS函数角度记录并查看内存的分配信息。点击Start按钮,执行你想要去深入分析的页面操作,当你完成你的操作后点击Stop按钮。然后会显示一个按JS函数进行内存分配的分解图,默认的视图是Heavy (Bottom Up),该视图会把最消耗内存的函数显示在最顶端。
下图是切换到Chart视图时具体的界面,点击任意函数跳转到Sources面板可以查看具体的函数信息。
参考文档
个人博客
Chrome开发者工具详解(4)-Profiles面板的更多相关文章
- 四、Chrome开发者工具详解(4)-Profiles面板
摘自: http://www.cnblogs.com/charliechu/p/6003713.html
- Chrome开发者工具详解(2)-Network面板
Chrome开发者工具详解(2)-Network面板 注: 这一篇主要讲解面板Network,参考了Google的相关文档,主要用于公司内部技术分享. Chrome开发者工具面板 面板上包含了Elem ...
- Chrome开发者工具详解(3)-Timeline面板
Chrome开发者工具详解(3)-Timeline面板 注: 这一篇主要讲解面板Timeline,参考了Google的相关文档,主要用于公司内部技术分享.. Timeline面板 Timeline面板 ...
- 三、Chrome开发者工具详解(3)-Timeline面板
摘自: http://www.cnblogs.com/charliechu/p/5992177.html
- 二、Chrome开发者工具详解(2)-Network面板
摘自: http://www.cnblogs.com/charliechu/p/5981346.html
- 【转】Chrome开发者工具详解
https://www.jianshu.com/p/7c8552f08e7a Chrome开发者工具详解(1)-Elements.Console.Sources面 Chrome开发者工具详解(2)-N ...
- Chrome开发者工具详解(5)-Application、Security、Audits面板
Chrome开发者工具详解(5)-Application.Security.Audits面板 这篇文章是Chrome开发者工具详解这一系列的最后一篇,介绍DevTools最后的三个面板功能-Appli ...
- Chrome开发者工具详解(1)-Elements、Console、Sources面板
Chrome开发者工具详解(1)-Elements.Console.Sources面板 Chrome开发者工具面板 面板上包含了Elements面板.Console面板.Sources面板.Netwo ...
- Chrome开发者工具详解(1):Elements、Console、Sources面板
Chrome开发者工具面板 面板上包含了Elements面板.Console面板.Sources面板.Network面板. Timeline面板.Profiles面板.Application面板.Se ...
随机推荐
- CSS3之绽放的花朵(网页效果--每日一更)
今天,带来的是纯CSS3打造的效果--绽放的花朵. 先来看效果吧:亲,请点击这里 这是纯CSS3样式打造的效果,关键是采用了animation属性和transform属性.详细请看下面代码. HTML ...
- RCP中如何使用代码安装、运行plugins
其实在google或者http://www.eclipse.org/forums/就能够找到这个问题的答案. 搜索关键字:rcp install plugins\bundles programmati ...
- Windows10 UWP开发 - 响应式设计
Windows10 UWP开发 - 响应式设计 本篇随笔与大家简单讨论一下在开发适配不同分辨率.宽高比的Windows10 Universal App布局时的可行方式与小技巧.经验均从实践中总结, ...
- Java多线程21:多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask
CyclicBarrier 接着讲多线程下的其他组件,第一个要讲的就是CyclicBarrier.CyclicBarrier从字面理解是指循环屏障,它可以协同多个线程,让多个线程在这个屏障前等待,直到 ...
- JavaScript思维导图—变量
JavaScript思维导图-来自@王子墨http://julying.com/blog/the-features-of-javascript-language-summary-maps/
- Unity3d热更新全书-加载(一)从AssetBundle说起
Unity3D动态下载资源,有没有解?有,AssetBundle就是通用解,任何一本书都会花大幅篇章来介绍AssetBundle. 我们也来说说AssetBundle 我们试全面的分析一下Unity3 ...
- 使用Guava提供的transform批量转换
实际开发了,为了快速查询,我们会把日期以Long类型的方式存储到数据库中,比如20000000000000L,但显示的时候,要完整的日期,即yyyy-MM-dd的格式显示. 这个时候,我们就可以使用C ...
- [分享黑科技]纯js突破localstorage存储上线,远程抓取图片,并转码base64保存本地,最终实现整个网站所有静态资源离线到用户手机效果却不依赖浏览器的缓存机制,单页应用最新黑科技
好久没有写博客了,想到2年前答应要放出源代码的也没放出来,最近终于有空先把纯js实现无限空间大小的本地存储的功能开源了,项目地址https://github.com/xueduany/localsto ...
- 大叔也说Xamarin~Android篇~监听返回键,单击返回某个webView,双击退出
回到目录 这个操作在原生android里是很容易实现的,在xamarin里也不难,在activity里有方法OnKeyDown,我们只需要重写一下就可以了,然后通过webView重新加载到要返回的页面 ...
- yar粗略使用记录
yar是鸟哥(laruence)开发的一个并行的RPC框架.据说sina weibo已经在大规模使用这个框架了.今天初步使用了下,觉得还是挺爽的一个工具. 什么情况适用这个工具呢? 比如一般你有个微博 ...