阅读更多
引用
原文:A Tale of JavaScript Performance
作者:Tom Lagier
翻译:Vincent

译者注:本文记录了作者对JavaScript性能的研究,以及遵循直觉工程的原则,将这些研究成果以何种方式进行展示,能够更直观地让用户了解。以下为译文。

本系列文章的目的是通过我正在进行的工作,即为Chrome内存配置文件创建可视化工具,来记录我对JavaScript性能的探索。我们将从当时创建这个项目的目的开始讲起,然后深入了解Chrome用于表示内存堆的文件格式。

直觉工程

数月前,我曾有机会去聆听了Casey Rosenthal一场关于直觉工程主题的精彩的演讲。直觉工程是一种概念,这种概念是指人们在理解信息时变得更容易,而不需要再去仔细思考。像视觉、声音和气味这样的东西,可以用阅读一段文字或者解释一个表格这么一小段时间来处理。

你能多快地了解这个应用服务器上发生了什么:

AWS CloudWatch日志监控器

那相比这个呢:

新Relic错误分析展示图

很显然,在适当的抽象层面上对数据进行可视化表示可以更容易地了解实际发生的情况。Casey说一旦你接触过这种抽象有一段时间,那么你就会形成一种直觉意识:“什么是正常的”。基线的变化是显而易见的,这样我们就可以利用人类的自然本能来进行模式识别,从而让我们深入了解可能导致行为变化的因素。

这使得直觉工程成为设计诊断接口的绝佳平台,特别是那些随着时间而显示数据的平台。通过提供一个允许用户开发直观基准的接口,您可以让用户快速区分每条基准线之间的区别。

项目就此诞生

对直觉工程有一个大概了解之后,我很想在个人项目上尝试一下。当时我正在研究一些JavaScript内存堆分析,试图诊断应用程序占用内存的原因,并追踪一些内存泄漏。

花费几天时间研究接口之后:

Chrome内存文件监控器

我想也许我可以利用这个直觉工程的想法来构建一个更好的堆快照视图。通过以可视化的方式呈现数据,我们可以快速了解内存分配的位置以及GC运行期间没有清理的内容。在应用程序中开发直观的基准可能很困难,但是随着时间的推移,应用程序当然可以有一个视觉上的理解,可以让我们快速识别重大事件或问题领域。

解码堆配置文件格式

如果我想要以可视化的方式表示堆配置文件,我的第一步需要将导出的Chrome堆概要文件格式解析为可以看到的东西。堆配置文件格式巧妙地压缩了JSON。它看起来像这样:

摘录自.heapprofile文件

这些文件非常大,通常是几百兆字节。这种格式花了我很长一段时间才搞清楚,但是我最终通过Chrome devtools进行了大量的试用和错误的方法,终于解决了这个问题。

内存表示为图形,节点表示内存分配,edge表示对这些内存位置的引用。 样本由时间戳和最后分配的edge组成。 该文件的每行代表其类型的一个对象。 对象的字段在元数据中标识为node_fields。

一个节点可以通过其edge_count字段来确定它的边。从第一个节点开始,edges递增地分配给节点。因此,第一个节点的edge_count为8,由前8个edge引用。 第二个节点edge_count为17,拥有接下来的17个edges,依此类推。

对父节点的edges引用不是由ID完成的,而是通过数组中节点的起始元素的索引来完成。 类似地,时间样本由样本中分配的最后一个edges的结束索引标记。 我花了很长时间才弄明白这一点,但好处是显而易见的——它创建了一个唯一的整数键,用于快速查找数组。不需要将整个图解析为数据结构,以便确定有关单个edges或节点的数据。

关于节点

对于任何给定的节点,有三个统计特别重要:
  • 自身大小-仅由节点本身单独存储的内存大小。 非常大的内存中对象将具有较大的自身大小,比如长字符串、字典和具有大主体的函数。寻找具有非常大的自身大小的对象通常是减少应用程序内存占用的第一步。
  • 保留大小-对象的自身大小加上所有被释放的对象的大小应该被删除。 在数学上,这个节点主导的任何节点(更多的是在一秒钟内)被添加到其保留的大小。 具有非常大的保留尺寸的对象如果被清理,将释放大量内存,即使它们没有特别大的自身尺寸。
  • 其保留者的身份 - 节点的任何边缘都提供了将内容保存在内存中的信息。 一旦你确定了一组呈现问题的节点,这是最重要的,因为它表明在内存中保留这些节点是什么。 保留者还可以为您提供关于标签不良节点的真实性质的有用线索。
第一个和第三个方法的作用是微不足道的-因为节点自身的大小是在定义节点时给出的,通过构建图形,您可以轻松找到节点的保留者。 然而,计算节点的保留大小并不是那么简单。 要计算它,我们必须首先拥有节点占主导地位的所有节点的列表。

建立支配树

如果遍历到根节点时,所有路径必须经过N,就认为节点就被节点N所主导。站在内存的角度,这就意味着如果你删除了从N到节点的引用,那么它就不会再有引用了,在下一次传递中会被垃圾回收站给回收掉。为了从图中生成一系列的支配节点,我们就需要创建支配树了。

有一种算法很容易就可以构建这样一种树,称为Tarjan-Lengauer算法。这个算法是相当有技术性的,我开始撸起袖子,还有很多疑问,就尝试用JavaScript去实现。我思考了一下并且稍微挖掘了一下,然后我就意识到,在我面前的是一个多么好的已经实现的开源算法。

OSS万岁

我知道Chrome devtools正在构建一个支配树,因为它们从文件中加载堆快照时,可以轻松地将其作为进程消息之一进行闪烁。快速地访问Chromium源代码后,让我想到了HeapSnapshot.js和朋友。我意识到——如果Chrome有一个开源的、可以用于生产的应用程序,那么我为什么还要自己去弄呢?

我现在很高兴地跟大家说,它运行得很好。我能够提取HeapSnapshot模块并在浏览器中进行旋转。我必须填补一些东西,但是devtools模块的目的是用来挂起一个全局对象,这样就可以轻易地进行抽取—只需提供您自己的、正确命名的全局对象,确保它们拥有所需的任何实用程序,并且它们将完成其余的工作。。

稍后,我还可以对它进行一些临时的操作,然后我就可以为它提供一个堆配置文件,并在最后得到一个完全膨胀的堆表示。我有了我的数据,准备好了,准备好了我想要的任何可视化方法!
  • 大小: 217.3 KB
  • 大小: 59.7 KB
  • 大小: 107.3 KB
  • 大小: 95 KB
0
0
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • JavaScript性能故事:选择可视化方法

    原文:A Tale of JavaScript Performance 作者:Tom Lagier 翻译:Vincent ...本文将继续介绍关于我对JavaScript性能调查的系列–通过为Chrome内存配置文件创建可视化工具进行记录。今天我...

  • 在Google Chrome和Visual Studio Code中调试JavaScript

    ) Download the Debugger for Chrome extension 下载Debugger for Chrome扩展程序 Create Debug configuration 创建调试配置 Launch Debug configuration 启动调试配置 Set breakpoints, inspect variables, etc....

  • 【Chrome插件开发】ReRes和request-interceptor源码赏析+复现+插件开发完整解决方案

    [这个项目](https://github.com/Hans774882968/hans-reres)主要目的是用前端工程化技术栈复现`ReRes`和`request-interceptor`,希望将两者的功能结合起来。`request-interceptor`是前端开发调试常用工具,提供了多种...

  • 性能基础知识(持续更新)

    6、一般应用性能分析 Firefox、Chrome 和其他浏览器包含内置工具,可以帮助您诊断页面渲染缓慢的情况。特别是,Firefox 的网络监视器将显示页面上每个网络请求发生的时间、大小以及需要多长时间的精确时间线。...

  • JavaScript 逆向 ( 一 ) --- JavaScript 语法基础、逆向技巧

    JavaScript 语法基础、逆向技巧

  • JavaScript 逆向 ( 一 ) --- JavaScript 语法基础

    js 逆向:https://www.cnblogs.com/wuxianyu/category/1940304.html js逆向... 名字空间 全局变量会绑定到window上,不同的JavaScript文件如果使用了相同的全局变量,或者定义了相同名字的顶层函数,都会造成命名冲突,...

  • HTTP/2 技术调研和性能分析

    转载自 | 小米运维(公众号 ID:MI-SRE)HTTP/2 协议简介 HTTP/2 是现行 HTTP 协议(HTTP/1.x)的替代,但它不是重写,HTTP ...HTTP/2 基于 SPDY3,专注于性能,最大的一个目标是在用户和网站间只用一个连接。 H...

  • 【收藏的JS库】 Javascript常用的库 (包含图片处理、动画库、语音命令库、视觉检测、机器学习等)

    velocity:加速 JavaScript 动画。 jquery.transit:拥有超级流畅的 CSS3 变换和过渡效果的 jQuery 插件。 impess.js:在 HTML 文档里,运用 CSS3 变换和过渡制作类似 Prezi 的展现效果。 bounce.js:可以立刻创建...

  • 6 个用于颜色生成的 JavaScript 工具

    颜色会刺激大脑——它们会影响你的思维方式和做出的决定。一种颜色或一组颜色可以构成身份的一部分。想想与 Google 相关的红色、黄色、绿色和蓝色。所有这一切都表明为您的项目选择正确的颜色集非常重要。进来颜色...

  • JavaScript Promise:去而复返

    作者:Jake Archibald 翻译:Amio 女士们先生们,请准备好迎接 Web 开发历史上一个重大时刻…… ... JavaScript 有了原生的 Promise! [漫天的烟花绽放,人群沸腾了] 这时候你大概是这三种人之...

  • javascript Promises

    原文地址:http://www.html5rocks.com/zh/tutorials/es6/promises/#toc-api女士们先生们,请准备好迎接 Web 开发历史上一个重大时刻……[鼓声响起]JavaScript 有了原生的 Promise![漫天的烟花绽放,人群沸腾了]这...

  • 【浏览器工作原理与实践笔记二】:浏览器中的页面循环系统

    文章目录【浏览器工作原理与实践笔记二】:浏览器中的页面循环系统一、消息队列和事件循环:页面是怎么活起来的使用单线程处理安排好的任务在线程运行过程中处理新任务处理其他线程发送过来的任务处理其他进程发送...

  • JavaScript Promises

    在浏览器中,JavaScript 和其他任务共享一个线程,不同的浏览器略有差异,但大体上这些和 JavaScript 共享线程的任务包括重绘、更新样式、用户交互等,所有这些任务操作都会阻塞其他任务。 作为人类,你是多线程的...

  • JavaScript

    JavaScript一、数值范围1、正零和负零:2、NaN:(1)含义(2)运算规则3.Infinity二、函数1、参数的省略2、传递方式3、同名参数4、argument对象(1)概念(2)与数组的关系(3)callee 属性5、闭包6.立即调用函数...

  • 无聊科技正经事周刊(第6期):纯粹的程序员与必然的中年危机

    通过反复的学习循环产生强烈的产品直觉 3、Facebook 工程师文化独特之处(中文) 作者在 Facebook 工作了 7 年,结合 Facebook 之前和之后的其它公司的经验,他觉得 Facebook 的文化有些 独特 的地方值得分享,并...

  • 整理15款实用javascript富文本编辑器 转自136go

    UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码... 2bootstrap-wysiwyg 官方网址:...

  • 实用javascript富文本编辑器

    UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码... 2bootstrap-wysiwyg 官方网址:...

  • webpack处理javascript兼容性--Babel

    . package允许你使用Babel和webpack转译JavaScript文件。因为javaScript的版本一直都在更新迭代,所以需要转译为浏览器可认识的文件内容,经常来说,我们会将ES6转换成ES5...1.1配置文件 { test:/\.js$/, exclude:

  • node-v7.7.2-linux-x86.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

Global site tag (gtag.js) - Google Analytics