Java - JVM - visualvm 简介

  1. 概述

    1. 今天聊聊 visualvm
  2. 背景

    1. 之前简单聊了聊 JVM 的 命令行工具

      1. jinfo
        1. JVM 启动参数
      2. jstat
        1. JVM 的 堆内存 以及 gc 情况
      3. jmap
        1. 做 堆内存 的 dump
      4. jhat
        1. 分析堆内存 dump
      5. jstack
        1. 分析 线程的情况
    2. 问题

      1. 命令行工具, 还是有些问题的
        1. 命令行工具 没那么好看
        2. 截取的内容, 都是一个瞬间
          1. 无法做趋势的比对
          2. 有时候要抓住某个瞬间, 还真有点难
    3. 解决

      1. 可以尝试用 图形工具, 来解决这些问题
        1. jmc
          1. 这个工具后面讲
        2. visualvm
          1. 这次就他了
        3. jconsole
          1. visualvm 是它的升级版, 所以就不聊它了
        4. jprofile
          1. 一款需要付费的软件, 暂时不提
          2. 据说很强大
  3. 环境

    1. OS
      1. win10
    2. Java
      1. 1.8.0_201
    3. demo
      1. Spring Boot
        1. 2.1.3
    4. shell
      1. win10 cmd

1. 准备

  1. 示例进程

    1. 随便起了个 spring-boot 的 webmvc 工程
      1. 写个 hello world 之类的就行
      2. 以下简称 demo
  2. 约定

    1. 后面只描述 本地执行 的结果
      1. visualvm 其实可以远程执行, 这个有兴趣的同学自己去研究吧

2. visualvm

  1. 概述

    1. 简介 visualvm
  2. visualvm

    1. java 可视化管理, 维修, 剖析工具

      1. 可视化
        1. 没错, 他有图形界面
      2. 剖析
        1. 信息应该会 很全面吧
    2. 启动

      1. 图形启动

        1. 路径

          $JAVA_HOME/bin/jvisualvm.exe
          
      2. 命令行启动

        1. 准备

          1. 确认 bin 目录在 classpath 里
        2. 命令

          > jvisualvm
          
      3. 一打开我就懵逼了

        1. 东西挺多从什么地方说起呢?
          1. 当然是从 最简单的 说起了

1. 控件 - 应用程序

  1. 概述

    1. 简述 应用程序 控件
  2. 内容

    1. 本地
      1. 能看到 本地运行 的 JVM 名称
        1. 规律我也不填清楚
          1. visualvm 和 idea 都是显示程序名
          2. 我的 demo 程序, 则是用的 main 类全名...
      2. 右键菜单
        1. 打开
          1. 可以查看本地 内存 和 交换空间 的信息
        2. 添加
          1. jmx 连接
          2. jstatd 连接
        3. 属性
          1. 展示本地描述
    2. 其他
      1. 水平有限, 就不瞎讲了
      2. 随缘补充
  3. 输入

    1. 由应用程序控件分析, visualvm 大概可以接受四种类型的输入
      1. 本地
      2. 远程
      3. VM 核心 dump
      4. 快照
    2. 这些具体是什么, 我好像现在也解释不了
      1. 先随便选个 本地 的 JVM 看看
  4. 右键菜单

    1. 操作

      1. 右键单击 JVM 实力, 弹出右键菜单
    2. 操作与现象

      1. 属性

        1. 打开后进入 属性窗口
          1. 名称
          2. 介绍
          3. 连接
            1. 直接 VM
            2. 本地 jvmstat
      2. 其他不说了

    3. 疑问

      1. 连接
        1. vm 和 jvmstat 有什么不同
  5. 后续

    1. 连接类型
      1. 选用 本地 jvmstat
        1. 大多数程序都是这个类型...

2. 控件 - 右侧主窗口

  1. 概述

    1. 简述 右侧主窗口
  2. 准备

    1. 双击之前启动的 demo 程序
      1. 右边立马出现一个 标签页
      2. 标签页下, 有 4 个子页面
        1. 我们一个一个看吧...

1. 概述

  1. 概述

    1. 概述页
  2. 内容

    1. 虚拟机名 与 pid

    2. 概述

      1. 进程信息
        1. pid
        2. 主机名
      2. JVM 信息
        1. JVM 的主类
          1. 就是 main 方法的位置
        2. 命令行参数
        3. JVM 名称版本
        4. Java 版本
        5. Java Home
        6. JVM 标志?
    3. 保存的数据

      1. 类型
        1. 线程 dump
        2. 堆 dump
        3. Profiler 快照
      2. 得知
        1. visualvm 可以捕捉这些类型
          1. 应用程序 右键菜单 就有选项, 可以创造这三种类型
    4. 参数

      1. JVM 参数
      2. 系统属性

2. 监视

  1. CPU 监控

    1. 方式
      1. 实时监控
    2. 内容
      1. cpu
        1. cpu 使用
        2. 垃圾回收活动
    3. 操作
      1. 鼠标移动到某个时间上, 会显示当时的占用率
  2. 内存

    1. 方式
      1. 实时监控
    2. 内容
        1. 当前容量
        2. 已经使用
        3. 最大容量
      1. metaspace
        1. 当前容量
        2. 已经使用
        3. 最大容量
    1. 方式
      1. 实时监控
    2. 内容
      1. 已装入的总量
      2. 已卸载的总数
      3. 共享的已装入数
      4. 共享的已卸载数
  3. 线程

    1. 方式
      1. 实时监控
    2. 内容
      1. 活动线程
      2. 实时峰值
      3. 守护线程
      4. 已启动的线程?
  4. 其他功能

    1. 触发 gc

      1. 图形
        1. 通常是那种 锯齿形
          1. 一次函数 的那种上升
          2. 一下垂直的下降
        2. gc 触发
          1. gc 触发确实可以提前那个下降
    2. 堆 dump

3. 线程

  1. 线程统计

    1. 实时线程
    2. 守护线程
  2. 线程可视化

    1. 时间线

      1. 放大
        1. 缩短采集间隔
          1. 提高数据精度
          2. 但是会影响 jvm 性能
        2. 最小间隔 50ms
      2. 缩小
        1. 和放大相反
        2. 最大间隔 30mins
      3. 适当
        1. 选了之后就没法调整了
        2. 但是具体精度是多少, 我也说不上来
          1. 我当时是 5mins
    2. 筛选

      1. 条件
        1. 所有
        2. 活动
        3. 完成
    3. 线程图表 一行

      1. 名称
        1. 线程名称
      2. 状态
        1. 每个时间段, 线程的状态
        2. 颜色 与 状态
          1. 运行 - 绿色
          2. 休眠 - 紫色
          3. 等待 - 黄色
          4. 驻留 - 橙色
          5. 监视 - 粉色
  3. 其他操作

    1. 线程 dump

4. 抽样器(Sample)

  1. 概述

    1. visualvm 下的 抽取器
  2. 抽样器 vs 分析器(Profiler)

    1. 机制
      1. 抽样器
        1. 基于 dump, 周期性的抓取数据
      2. 分析器
        1. 基于 bytecode, 添加字节码, 从而监控所有方法的调用情况
    2. 结果
      1. 抽样器
        1. 精度不如 分析器
        2. 性能影响小
      2. 分析器
        1. 精度较高
        2. 性能影响较大
      3. 特别是在 堆内存 上, 这俩的结果完全不同
        1. 抽样器 的 数值, 基本都要比 分析器 大
          1. 类数量
          2. 类占用空间
          3. 实例数
        2. 抽样器 的结果, 是 dump, 整个堆的一个复制
          1. 100% 的完全重现
        3. 分析器 的结果, 是 阶段性的结果
          1. 记录的时间起点, 是你开始分析的时刻, 到当前时间, 或者你停止分析的时刻
          2. 这是一个 增量 的记录
  3. CPU 抽样

    1. 设置

        1. 可以用 黑名单/白名单 的方式, 追踪具体的包
      1. 抽样率
        1. 可以调整抽样的精度
    2. 基本操作

      1. 开启
        1. 单击 抽样 后的 CPU 按钮
          1. 单击后 状态 变为 正在进行 CPU 抽样
          2. 下面的 标签页, 出现内容
          3. 内容会随 结果刷新 的时间变动
      2. 停止
        1. 单击 停止 按钮
      3. 暂停
        1. 暂停刷新
        2. 但是抽样应该在继续
      4. 刷新
        1. 前提
          1. 暂停抽样
        2. 结果
          1. 立即更新抽样数据
      5. 排序
        1. 结果的表格, 支持按照列排序
          1. 正序
          2. 倒叙
      6. 筛选
        1. 结果的表格, 支持
          1. 最下面
    3. CPU 样例 - 方法维度

      1. 数据 - 行

        1. 方法
          1. 统计的 方法
        2. 自用时间 百分比
          1. 线程自用时间, 占 总共自用时间 的百分比
        3. 自用时间
          1. 自用
            1. 只包含 该行方法 的时间
            2. 不包含 调用/执行其他方法 花费的时间
          2. 时间
            1. 包含
              1. cpu 时间
              2. 等待
              3. 休眠
        4. 自用时间(CPU)
          1. 自用 cpu 时间
        5. 总时间
          1. 包含了 该行方法 和 调用/执行其他方法 花费的时间
        6. 总时间(CPU)
          1. 包含了 该行方法 和 调用/执行其他方法 花费的 CPU时间
        7. 样例
          1. 调用方法的最低次数
        8. 自定义
          1. 每行显示的数据, 可以做 自定义, 这个我就不下车了
      2. 操作

        1. 快照
          1. 可以生成 snapshot
            1. 快照后面集中再讲
    4. 线程 CPU 时间 - 线程维度

      1. 统计

        1. 线程数
        2. 总 CPU 时间
      2. 数据 - 行

        1. 线程名称
          1. 线程名称
        2. 线程 CPU 时间 [%]
          1. 线程占用的 CPU 时间百分比
            1. 总时间
        3. 线程 CPU 时间 [毫秒]
          1. 线程占用的 CPU 总时间
          2. 数据后面的 % 我没看懂
        4. 线程 CPU 时间 [毫秒]/秒
          1. 线程上一秒 占用的 CPU 时间
      3. 操作

        1. 增量
          1. 显示当前时刻开始的增量统计
          2. 再点一下又切回总时间统计
  4. 内存抽样

    1. 设置

      1. 抽样率
    2. 基本操作

      1. 开启
        1. 单击 内存 按钮
      2. 停止
        1. 单击 停止 按钮
          1. cpu 和 内存 抽样可以不同时进行
          2. 当前查看哪个, 停止的时候, 就停止哪个
      3. 暂停
        1. 同 cpu抽样
      4. 刷新
        1. 同 cpu抽样
      5. 排序
        1. 同 cpu抽样
      6. 筛选
        1. 同 cpu抽样
    3. 堆柱状图

      1. 统计

        1. 实例
        2. 字节
      2. 数据 - 行 - 没啥好解释的, 比 jhat 友好多了...

        1. 类名
        2. 字节[%]
        3. 字节
        4. 实例数
      3. 操作

        1. 增量
          1. 查看从现在开始的 增量
        2. 快照
          1. 产生 快照
          2. 后面再讲
        3. 执行 GC
        4. 堆 dump
          1. 后面再讲
    4. 每个线程分配

      1. 统计

        1. 线程
        2. 已分配的总字节数
      2. 数据 - 行

        1. 线程名称
        2. 已分配的字节 [%]
        3. 已分配的字节
        4. 已分配的字节 /秒
      3. 操作

        1. 增量
        2. 执行 GC
        3. 堆 dump

5. 分析器

  1. 概述

    1. 简述 分析器
  2. CPU 分析器

    1. 设置

      1. 从类启动性能分析

        1. 启动
          1. 调用列表里的类代码, 会启动性能分析
          2. 只是个 开关
          3. 具体决定要分析那些类, 由后面决定
        2. 格式
          # 一行一个范围
          # 1. 某个类
          com.demo.Class
          # 2. 某个包中类
          com.demo.*
          # 3. 某包中类及其子类
          com.demo.**
          # 4. 所有类
          空白, 什么都不写
          
      2. 分析新的可运行对象

        1. 会对新线程进行分析
      3. 黑白名单

        1. 要分析/不分析的类
          1. 注意上面选的是 黑名单 还是 白名单
      4. 预设

        1. 这个我也没怎么看
    2. 基本操作

      1. 开启
        1. 单击 性能分析 后的 CPU 按钮
          1. 单击后 状态 变为 正在进行 CPU 分析
          2. 下面的 标签页, 出现内容
          3. 内容会随 结果刷新 的时间变动
      2. 停止
        1. 单击 停止 按钮
      3. 自动更新结果
        1. 选中后, 会自动刷新
        2. 补选中, 刷新会停止, 但是分析应该在继续
      4. 立即更新结果
        1. 前提
          1. 自动跟新结果 未选中
        2. 结果
          1. 立即更新分析数据
      5. 垃圾回收并更新结果
        1. 这个不懂
      6. 重置收集的结果缓冲区
        1. 清空之前的结果
        2. 重新开始收集
      7. 快照
        1. 产生快照
      8. 导出至
        1. 输出一个 xml
          1. 记录当前的情况
      9. 将当前视图另存为图像
        1. 输出一个图片
          1. 记录当前的情况
      10. 排序
        1. 结果的表格, 支持按照列排序
          1. 正序
          2. 倒叙
      11. 筛选
        1. 结果的表格, 支持
          1. 最下面
    3. 数据 - 行

      1. 热点 - 方法
        1. 被统计的方法名
      2. 自用时间[%]
      3. 自用时间
      4. 总时间
      5. 调用
        1. 方法调用的次数
  3. 内存分析器

    1. 设置

      1. 记录内容
        1. 分析对象分配
          1. 只记录对象分配
        2. 分析对象分配和 GC
          1. 记录对象的整个 生命周期
      2. 全部跟踪
        1. 以 n 个对象为一组跟踪
        2. 不太懂
      3. 记录分配栈跟踪
        1. 不太懂
      4. 预设
        1. 不太懂
    2. 基本操作

      1. 同 CPU 分析器
    3. 数据 - 行

      1. 类名 - 活动的分配对象
      2. 活动字节[%]
      3. 活动字节
      4. 活动对象
      5. 年代数
        1. 存活的垃圾回收次数
    4. 注意

      1. CPU 分析 和 内存分析, 不能同时开启

ps

  1. ref

    1. 官方引导
      1. 感觉效果不是很好
    2. Profiling Vs. Sampling in Java’s VisualVM
      1. sample vs profiler
    3. Spring Boot+Spring Cloud+Vue+Element项目实战
      1. 一个实战
        1. 网易的老哥通过言传身教, 告诉我们, 他们自己的 json 模块性能不好
        2. 更倒霉的是, 最后居然换上了 fastjson...
    4. 【Java VisualVM】使用 VisualVM 进行性能分析及调优
      1. 一个更加走心的实战
    5. VisualVM and Self Time
      1. self time 的解释
        1. 为数不多的解释
      2. 其实, 把鼠标悬停在表头, 自己就会出现解释
        1. 最后知道真相的我眼泪掉下来
  2. 疑问

    1. 问题1
      1. 共享的装入卸载, 如何触发
    2. 问题2: 线程统计里的 已启动总数
      1. 本质上还是不知道 四个量 之间的关系
    3. 问题3: 线程状态, 驻留, 监视
      1. 这俩状态我搞不懂
    4. 问题4: sampler 和 profiler 的 堆内存数据
      1. 这俩数据有什么区别, 内容为什么不一样
  3. 后续

    1. 啰嗦半天总算把最基本的东西说完了...
      1. 基本就是记下了个流水账
      2. 缺失的东西是 各项指标的意义, 以及具体的使用场景
    2. 后续内容
      1. 快照
        1. visualvm 有各种快照, 这里来不及说了
      2. 插件
        1. 插件的安装, 其实很简单, 自己看看就会了, 我也不废话了
posted @ 2020-04-18 18:01  轩辕拾銉  阅读(929)  评论(0编辑  收藏  举报