当前位置:K88软件开发文章中心编程工具Chrome → 文章内容

Chrome开发工具 JavaScript 内存分析

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-24 11:01:34

的细节在本节中,我们所讲的是对应 V8 JavaScript 虚拟机(V8 VM 或者 VM)的内存方面的话题。这些内容对于理解堆快照为何是上面所看到的那个样子很有帮助。JavaScript 对象的表示JavaScript 中有三种主要类型:数字(比如,3.14159..)布尔值(true 或者 false)字符串 (比如 "Werner Heisenberg")这些类型在树中都是叶子节点或者终结节点,并且它们不能引用其它值。数字类型可以像下面这样存储:相邻的 31 位整数值,被称为 small integers (SMIs)被称为堆数字的堆对象。堆数字用于存储不适合 SMI 形式的值,比如浮点类型,或者是需要封装的值,比如设置其属性值的类型。字符串可以被存储在:虚拟机的堆中外部的渲染内存。也就是当创建或者使用一个封装后的对象时需要使用的外部存储器,比如,脚本资源以及其他从网上接收而不是赋值到虚拟机堆中存储的内容。新的 JavaScript 对象的内存是由特定的 JavaScript 堆(或者说 VM 堆)分配的。这些对象由 V8 垃圾回收器管理,并且只要存在一个对他们的强引用就不会被回收。本地对象指的是不在 JavaScript 堆中存储的一切对象。本地对象和堆对象相反,其生存周期不由 V8 垃圾回收器管理,并且只能通过封装它们的 JavaScript 对象来使用。Cons string 是一个保存了成对字符串的对象,并且该对象会将字符串拼接起来,最后的结果是串联后的字符串。拼接后的 cons string 的内容只有在需要的时候才会出现。一个比较好的例子就是,如果想获取某个字符串的子串,就必须利用函数进行构建。举个例子,如果你将 a 和 b 对象串联,那么你将获得一个字符串(a,b) 用于表示拼接后的结果。如果你之后又加入了一个对象 d,那么你将活的另一个字符串((a,b),d)。数组 - 一个数组就是有着数字键的对象。他们广泛应用在 V8 VM 中,用于存储大量数据。在字典这样的数据结构中键值对的集合就是利用数组来备份的。一个典型的用于存储的 JavaScript 对象可以是下列两种数组类型之一:命名的属性数字元素如果想要存储的是少量的属性,那么它们可以直接在 JavaScript 对象中存储。Map - 一个对象,用于描述对象及其布局的种类。举个例子,maps 用于描述快速属性访问的隐式对象结构。对象组每个本地的对象组都是由保持彼此相互引用的对象组成的。以一个 DOM 子树为例,在该树中,每一个节点都一个指向父节点的连接,以及指向孩子节点和兄弟节点的链接,由此,所有的节点连成了一张图。需要注意的是,本地对象并不会在 JavaScript 堆中出席那,所以它们的大小是 0。相应的,对于每个要使用本地对象都会创建一个对应的封装对象。每个封装对象都含有一个对相应的本地对象的引用,这是为了能够将命令重定向到本地对象上。而对象组则含有这些封装的对象,但是,这并不会造成一个无法回收的死循环,因为垃圾回收器会自动释放不在引用的封装对象。但是一旦忘记了释放某个封装对象就可能造成整个组以及相关封装对象都无法被释放。先决条件以及一些有用的提示Chrome 任务管理器注意:在 Chrome 中分析内存问题时,一个比较好的方法就是配置 clean-room testing 环境。如果某个页面消耗了大量内存,可以在执行有可能占用大量内存的活动时使用 Chrome 任务管理器的内存这一栏来监视页面所占用的内存。如果要使用任务管理器,点击 menu > Tools 或者使用快捷键 Shift + Esc。打开之后,右键点击列头部分然后启用 JavaScript memory 列。使用 DevTools 时间轴来找出内存问题要解决问题的第一步就是要先拥有找出问题的能力。这意味着能够创建一个用于基本问题测量的可重复性测试。如果没有一个可复用的程序,你就没办法有效地衡量问题。另外,如果连测试基线都没有的话,就没办法知道做出的改变是否提高了程序的性能。时间轴面板对于发现问题出现的时间非常有帮助。页面或者应用程序加载或者进行交互时,它会给出整个流程的时间消耗的完整概述。所有的事件,从加载资源到解析 JavaScript、计算样式、垃圾回收以及重绘都会出现在时间轴上。在寻找内存问题的时候,时间轴面板的 Memory view 可以用来追溯:总共分配的内存 - 内存的使用量是否增长了?DOM 节点的数量。文档的数量分配的事件监听器的数量。想要了解在内存分析时找出可能造成内存泄露的问题的更多信息,请查看 Zack Grossbart 写的 Memory profiling with the Chrome DevTools验证存在的问题首先要做的事情就是找出你认为可能造成内存泄露的活动。这种活动可能是任何事情,就像是在站点上进行定位、鼠标的悬停事件、点击事件或者是与页面交互时可能对性能产生消极影响的事件。在时间轴面板中,开始记录(Ctrl + E 或者 Cmd + E)然后执行你想测试的活动序列。要强制进行垃圾回收,点击底部的垃圾图标()。在下图中我们可以发现有些节点没有被回收,而这些节点所对应的图案就是内存泄露的图案样式:如果在几次迭代后你看见了一个锯齿形的图案(在内存面板的顶部),这就说明你分配了大量短生存期的对象。但是,如果这个操作序列并没有使内存保留下来,或者 DOM 节点的数量并没有下降到刚开始执行时的那个基线上,那么你有很好的理由来怀疑这里发生了内存泄露。一旦你确认了存在问题,你就可以借助 Profiles panel 中的 heap profiler 找出问题的来源。示例:你可以尝试一下这个例子来锻炼一下如何高效使用时间轴内存模式。垃圾回收垃圾回收器(就像是 V8)能够定位到你的程序处于生存期的对象以及已经死亡的对象,甚至是无法访问到的对象。如果垃圾回收器(GC)由于某些逻辑错误没能回收你的 javaScript 中已死亡的对象,那么它们所消耗的内存将无法被再次使用。像这样的情况最终会随着时间推移而使得你的应用程序的执行速率不断变慢。如果你在编写代码时,即使是不再需要的变量以及事件监听器依旧被其他代码所引用,最终就会出现这种情况。当这些引用存在的时候,垃圾回收器就没办法正确清理这些对象。在你的应用程序的生存期间会有一些 DOM 元素更新/死亡,别忘了检出并消除引用了这些元素的变量。检查可能引用了其他对象(或者其他 DOM 元素)的对象的属性,并留意可能随着时间的推移不断增长的变量缓存。堆分析器生成快照在配置面板中,选择 Take Heap Snapshot,然后点击 Start 或者使用 Cmd + E 或 Ctrl + E 快捷

上一页  [1] [2] [3] [4] [5]  下一页


Chrome开发工具 JavaScript 内存分析