zoukankan      html  css  js  c++  java
  • Chrome 开发工具之 Memory

    开发过程中难免会遇到内存问题,emmm... 本文主要记录一下Chrome排查内存问题的面板,官网也有,但有些说明和例子跟不上新的版本了,也不够详细...
     
    !!! 多图预警!!! 
     
    简单的内存信息列表
     
    如果只想查看当前浏览器的各个 tab 正在使用的内存量,则在 Setting - More Tools - Task Manager 即可。效果如下图:
     
     
    那个列表里的可勾选项,没看错,是对于可选的信息数据列。
     
    那个 End Process 按钮,没看错,选择一项后,可以在浏览器所起的任务列表里关闭改任务(任务可以是打开页面的 tab、Chrome 自身一些项目及扩展插件...为什么不是按钮上写的 process,因为这些任务里面只有部分是在机器进程列表里列出存在的,强行严格 ~ToT~ )
      
    需要看内存的实时变化过程,可以在 Chrome - Performance 面板查看时间轴上内存变化情况,其中会有 `js Heap` 记录的选项,详情参考 Chrome 开发工具之 Timeline/Performance
     
    Memory 面板初始
     
    如果想要看更多的内存信息快照,则需要打开 Chrome 浏览器的开发者工具中的 Memory 面板了,下面就简单介绍一下该面板的使用。
    它大概是长这样:
     

    上面有三个按钮:

    • Heap snapshot - 用以打印堆快照,堆快照文件显示页面的 javascript 对象和相关 DOM 节点之间的内存分配
    • Allocation instrumentation on timeline - 在时间轴上记录内存信息,随着时间变化记录内存信息。
    • Allocation sampling - 内存信息采样,使用采样的方法记录内存分配。此配置文件类型具有最小的性能开销,可用于长时间运行的操作。它提供了由 javascript 执行堆栈细分的良好近似值分配。
     
    各自举些例子吧,方便理解
     
    Heap snapshot
     
    给个 html,里面只有一句 js 代码 var _____testArray_____ = [ {value: 'hello'} ]; ,打个堆栈看看:
     
     
    右上那块区域,从左到右有三个操作:查看方式、对象归类的筛选、对象选择。
     
    左边有 `Summary` 字样的那个,可以选择查看内存快照的方式,可选方式如下:
    • Summary - 可以显示按构造函数名称分组的对象。使用此视图可以根据按构造函数名称分组的类型深入了解对象(及其内存使用),适用于跟踪 DOM 泄漏。
    • Comparison - 可以显示两个快照之间的不同。使用此视图可以比较两个(或多个)内存快照在某个操作前后的差异。检查已释放内存的变化和参考计数,可以确认是否存在内存泄漏及其原因。
    • Containment - 此视图提供了一种对象结构视图来分析内存使用,由顶级对象作为入口。
    • Statistic - 内存使用饼状的统计图。
    附上 Comparison 效果,大致如下:
    代码:
    var _____testArray_____ = [{ value: 'hello' }]
    
    function someTodo() {
      _____testArray_____.push({
        value: ':::::::::'
      })
    }
    
    document.querySelector('#btn').addEventListener('click', someTodo, false)
     
    点击按钮后,数组中 push 了新的一项对象
    图(array 那块列表展开就看不到下面列表了,就没展开):
     
    附上 Containment 视图,它的排列稍微有些不同,大致如下:
    入口有:
    • DOMWindow - 是被视为 JavaScript 代码 "全局" 对象的对象。
    • GC - VM 的垃圾使用的实际 GC 根。GC 根可以由内置对象映射、符号表、VM 线程堆栈、编译缓存、句柄作用域和全局句柄组成。
    • 原生对象 - 是 "推送" 至 JavaScript 虚拟机内以允许自动化的浏览器对象,例如 DOM 节点和 CSS 规则。
     
    中间的 `Class filter` 只能够按照列出来的 Constructor 值进行筛选。
     
    右边的 `All objects` 能够选择查看哪些阶段的对象、如 "Objects allocated before Snapshot1"、"Objects allocated between Snapshot1 and Snapshot2"

    右中那块区域显示的内存快照信息,可以在各个数据上右键选择一些操作( `Reveal in Summary view` ),各个字段代表信息如下:
    • Contructor - 表示使用此构造函数创建的所有对象
    • Distance - 显示使用节点最短简单路径时距根节点的距离
    • Shallow Size - 显示通过特定构造函数创建的所有对象浅层大小的总和。浅层大小是指对象自身占用的内存大小(一般来说,数组和字符串的浅层大小比较大)
    • Retained Size - 显示同一组对象中最大的保留大小。某个对象删除后(其依赖项不再可到达)可以释放的内存大小称为保留大小。
    • #New - Comparison 特有 - 新增项
    • #Deleted - Comparison 特有 - 删除项
    • #Delta - Comparison 特有 - 增量
    • Alloc. Size - Comparison 特有 - 内存分配大小
    • Freed Size - Comparison 特有 - 释放大小
    • Size Delta - Comparison 特有 - 内存增量

    右下那块区域显示的是被选中对象的详细信息,如上面图片的内容一样一样的...可以在各个数据上右键选择一些操作( `Reveal in Summary view` )。

    注意:图中最最下面那块最有用,就是搜索,ctrl/command + f 唤出 ~

    最后,根据上面的图来分析一下上面代码产生的效果,根据 js 的类型和引用的关系来分析,变量 _____testArray_____ 在列表中的情况是:
    • 基础类型 string 值为 hello ,内存标记是 string@353953,这个 string 值存在于 Object @362113 对象上的 value 属性上;
    • Object @362113 在 Object 列表里,在 Array @356493 的索引 0 位置存在该对象的引用;
    • Array @356493 在 Window / @353829 对象上存在引用,属性名为"___testArray___";
    • Window / @353829 是个 Windows 对象,在 Windows 列表里。 
    "hello" -> 在(string)列表里 -> string@353953 -> value in Object @362113
    
        Object  -> 在 Object 列表里 -> [0] in Array @356493
    
            Array -> 在(array)列表里 -> _____testArray_____ in Window / @353829
    
                    Windows ->  在 Windows 列表里 -> Window / @353829
     
    Allocation instrumentation on timeline
     
    看完静态的快照,再来看看动态的。
    代码如下:
    var _____testArray_____ = [{ value: 'hello' }]
    var count = 1
    
    function someTodo() {
      // 每次点击 字符串长度都以上一次为基础增加到5倍,拉大差异突出效果,并且之后在字符串头部加上count值做区分
      count *= 5
      var str = new Array(count * 10).join(':')
      _____testArray_____.push({
        value: count + str
      })
    }
    
    document.querySelector('#btn').addEventListener('click', someTodo, false)
     
    选择 Allocation instrumentation on timeline 点击开始记录的按钮,然后得到如图所示:
     
    每条线的高度与最近分配的对象大小对应,竖线的颜色表示这些对象是否仍然显示在最终的堆快照中。蓝色竖线表示在时间线最后对象仍然显示,灰色竖线表示对象已在时间线期间分配,但曾对其进行过垃圾回收。(这图中不是很明显,放大 devtool 面板后,图中的蓝色线顶部是有部分是灰色的...)
     
    可以选择时间范围,查看该时间范围内的内存变化情况,如上图 5 次变化的情况分别是:
    # 前面的数字代表本次记录索引,点击了5次
    
    # 0  Shallow Size : 112
    Constructor         Distance   Shallow Size    Retained Size
    - - - - - - - - - - - - - - - - - - - - - - - - -  - - - - - - - - - - -
    (array)×9                3      5008  0%         5008  0%
    (system)×60              3      2416  0%         2640  0%
    (closure)×1              3      4768  0%         2928  0%
    Object×3                 3      144   0%         768   0%
    MouseEvent×3             4      112   0%         7200  0%
    (string)×2               5      96    0%         96    0%
    (concatenated string)×2  4      64    0%         160   0%
    Event                    5      56    0%         2040  0%
    UIEvent                  5      32    0%         648   0%
    
    # 1
    (string)×2               5      296   0%         296   0%
    (concatenated string)×2  4      64    0%         360   0%
    Object                   3      32    0%         392   0%
    
    # 2
    (string)×2               5      1296  0%         1296  0%
    (concatenated string)×2  4      64    0%         1360  0%
    Object                   3      32    0%         1392  0%
    
    # 3
    (string)×2               5      6296  0%         6296  0%
    (concatenated string)×2  4      64    0%         6360  0%
    Object                   3      32    0%         6392  0%
    
    # 4
    (string)×2               5      31296 0%         31296 0%
    (array)                  4      80    0%         80    0%
    (concatenated string)×2  4      64    0%         31360 0%
    (system)                 4      32    0%         32    0%
    Object                   3      32    0%         31392 0%
    当勾选 Record allocation stacks 框后,还可以在 Allocation stack 面板里打印出调用堆栈。
    如上面代码的效果:
    Allocation sampling
     
    这个功能根据名称和说明,不是很看得懂是什么... 但是,还是通过一些案例给出了效果图,如下:
    根据给出的图,可以看出这块的功能应该是:哪些函数影响了内存的分配,并且该函数所耗内存在内存分配中占比多少。
    图中函数可以直接点击跳转到函数定义的文件和位置。

    记录完毕,撒花...
     
  • 相关阅读:
    std::bind 详解及参数解析
    c++ 静态类成员函数(static member function) vs 名字空间 (namespace)
    继续进发
    lua闭包
    Mysql按时间段分组查询来统计会员的个数
    linux安装配置sendmail实现邮件发送
    Javascript验证用户输入URL地址是否正确
    php返回json数据函数例子
    ArrayList与List对象用法与区别
    java 获取数组(二维数组)长度实例程序
  • 原文地址:https://www.cnblogs.com/ys-ys/p/11336811.html
Copyright © 2011-2022 走看看