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
     
    这个功能根据名称和说明,不是很看得懂是什么... 但是,还是通过一些案例给出了效果图,如下:
    根据给出的图,可以看出这块的功能应该是:哪些函数影响了内存的分配,并且该函数所耗内存在内存分配中占比多少。
    图中函数可以直接点击跳转到函数定义的文件和位置。

    记录完毕,撒花...
     
  • 相关阅读:
    STL源码剖析之_allocate函数
    PAT 1018. Public Bike Management
    PAT 1016. Phone Bills
    PAT 1012. The Best Rank
    PAT 1014. Waiting in Line
    PAT 1026. Table Tennis
    PAT 1017. Queueing at Bank
    STL源码剖析之list的sort函数实现
    吃到鸡蛋好吃,看看是哪只母鸡下的蛋:好用的Sqlite3
    cJSON
  • 原文地址:https://www.cnblogs.com/ys-ys/p/11336811.html
Copyright © 2011-2022 走看看