-
概述
- jstat 的简单使用
-
背景
- jvm 是面试经常被问到的东西
- 面试造火箭 的典型
- 面试完了, 基本不用, 所以就会被渐渐忘记
- 我一直觉得, 这些监控工具, 是 性能调优 的基础
- 看都看不清, 后续根本没法做
- jvm 是面试经常被问到的东西
-
环境
- OS
- win10
- Java
- 1.8.0_201
- demo
- Spring Boot
- 2.1.3
- Spring Boot
- shell
- win10 cmd
- OS
1. 准备
- jps
- 作用
- 查找 java 进程的 pid
- jstat 命令需要基于 java 进程的 pid
- 作用
2. jstat
-
概述
- jstat 是什么
-
jstat
-
Java 工具
- 统计 运行时 jvm 的信息
-
信息
- 内存信息
- 堆栈容量
- gc 信息
- 编译信息
- 其他
- 内存信息
-
3. 基本格式
-
概述
- 命令基本格式
- 这里只讲 本地调试
-
格式
# option 是命令行选项 # pid 是目标进程的 pid # interval 是时间间隔, 单位是 ms > jstat <option> <pid> [interval]
-
例子
# 假设 pid 是 18436 # 1. 没有 interval, 只执行一次 > jstat -class 18436 # 2. interval = 1000ms, 每隔 1s 执行一次 # 可以通过使用单位 s 来调整, 这个我就不细说了 > jstat -class 18436 1000
4. 简单使用
- 概述
- 简单使用命令
- 例子不带 interval
1. 类加载统计
-
命令
>jstat -class 18436 Loaded Bytes Unloaded Bytes Time 6700 12069.9 1 0.9 2.03
-
解释
- Loaded
- 已经加载的类 数量
- 6700 个
- 已经加载的类 数量
- Bytes
- 已经加载的类 大小
- 12069.9 kB
- 已经加载的类 大小
- Unloaded
- 卸载的类 数量
- 1 个
- 卸载的类 数量
- Bytes
- 卸载的类 大小
- 0.9 kB
- 卸载的类 大小
- Time
- 装载 和 卸载 的总时间
- 2.03 s
- 装载 和 卸载 的总时间
- Loaded
-
疑问
- unloaded 的理解
- 问题
- unloaded 到底是什么意思
- 思考
- 未加载
- 没有加载的话, 为什么要统计 Bytes
- 没有装在的话, Time 里为什么要占用时间
- 未加载
- 结果
- Unloaded 是指卸载
- 曾经装载过, 并且目前已经不在 堆内存 里了
- Unloaded 是指卸载
- 问题
- unloaded 的理解
2. 编译统计
-
命令
>jstat -compiler 18436 Compiled Failed Invalid Time FailedType FailedMethod 3456 0 0 0.63 0
-
解释
- Compiled
- 编译的类
- 3456 个
- 编译的类
- Failed
- 编译失败的类
- 0 个
- 编译失败的类
- Invalid
- 非法的类
- 0 个
- 非法的类
- Time
- 编译时间
- 0.63 s
- 编译时间
- FailedType
- 失败类型
- 0 个
- 失败类型
- FailedMethod
- 失败的方法
- 无
- 失败的方法
- Compiled
-
疑问
- 编译
- HotSpot VM 的 JIT 编译
- 老实说, 这块我不熟...
- HotSpot VM 的 JIT 编译
- 编译
3. 编译情况
-
命令
>jstat -printcompilation 18436 Compiled Size Type Method 3456 201 1 org/apache/coyote/AbstractProtocol startAsyncTimeout
-
解释
- Compiled
- 同 编译统计
- Size
- 最近 被编译类 的大小
- 201 kB
- 最近 被编译类 的大小
- Type
- 最近 被编译类 编译类型
- 1
- 最近 被编译类 编译类型
- Method
- 最近被编译的方法
- org/apache/coyote/AbstractProtocol 下的 startAsyncTimeout 方法
- . 被换成了 /
- 最近被编译的方法
- Compiled
-
疑问
- 编译类型
- 这个 1 是什么意思?
- 编译类型
4. gc 统计概览
-
命令
>jstat -gcutil 18436 S0 S1 E O M CCS YGC YGCT FGC FGCT GCT 0.00 26.91 18.76 3.27 94.45 90.38 3 0.025 1 0.017 0.042
-
解释
- S0
- S0区 使用率
- 0%
- S0区 使用率
- S1
- S1区 使用率
- 26.91%
- S1区 使用率
- E
- 伊甸区 使用率
- 18.76%
- 伊甸区 使用率
- O
- 老年区 使用率
- 3.27%
- 老年区 使用率
- M
- 元数据区 使用率
- 94.45%
- 元数据区 使用率
- CCS
- 压缩类型区 使用率
- 90.38%
- 压缩类型区 使用率
- YGC
- 青年代 gc 次数
- 3 次
- 青年代 gc 次数
- YGCT
- 青年代 gc 时间
- 0.025 s
- 青年代 gc 时间
- FGC
- 完全 gc 次数
- 1 s
- 完全 gc 次数
- FGCT
- 完全 gc 时间
- 0.017 s
- 完全 gc 时间
- GCT
- 所有 gc 总共用时
- 0.042 s
- 结果的由来, 是 YGCT + FGCT 的值
- 所有 gc 总共用时
- S0
-
问题
-
堆内存的组成
- 模糊的感觉
-
青年代
- 伊甸区
- S0
- S1
-
老年区
-
元数据区
- 压缩类型
-
- 模糊的感觉
-
区域划分的原因, 每个区域的责任
- 后续
-
对象在各个区域间, 运动的规律
-
gc 触发的规律
-
5. gc 统计
-
命令
>jstat -gc 18436 S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT 43520.0 43520.0 0.0 11712.6 262144.0 63436.5 455168.0 14880.5 34560.0 32641.5 4864.0 4395.9 3 0.025 1 0.017 0.042
-
解释
- S0C
- S0区 当前大小
- 43520 kB
- S0区 当前大小
- S1C
- S1区 当前大小
- 43520 kB
- S1区 当前大小
- S0U
- S0区 使用
- 0 kB
- S0区 使用
- S1U
- S1区 使用
- 11712.6 kB
- S1区 使用
- EC
- 伊甸区 当前大小
- 262144.0 kB
- 伊甸区 当前大小
- EU
- 伊甸区 使用
- 63436.5 kB
- 伊甸区 使用
- OC
- 老年区 当前大小
- 455168.0 kB
- 老年区 当前大小
- OU
- 老年区 使用大小
- 14880.5 kB
- 老年区 使用大小
- MC
- 元数据区 当前大小
- 34560.0 kB
- 元数据区 当前大小
- MU
- 元数据区 使用大小
- 32641.5 kB
- 元数据区 使用大小
- CCSC
- 压缩内存区 当前大小
- 4864.0 kB
- 压缩内存区 当前大小
- CCSU
- 压缩内存区 使用大小
- 4395.9 kB
- 压缩内存区 使用大小
- YGC
- 青年代 gc 次数
- 3 次
- 青年代 gc 次数
- YGCT
- 青年代 gc 时间
- 0.025 s
- 青年代 gc 时间
- FGC
- 完全gc 次数
- 1 次
- 完全gc 次数
- FGCT
- 完全gc 时间
- 0.017 s
- 完全gc 时间
- GCT
- 总 gc 时间
- 0.042 s
- 总 gc 时间
- S0C
6. gcold
-
命令
>jstat -gcold 18436 MC MU CCSC CCSU OC OU YGC FGC FGCT GCT 34560.0 32641.5 4864.0 4395.9 455168.0 14880.5 3 1 0.017 0.042
-
解释
- 都快写完了, 发现好像之前已经解释过了
- 于是我删除了...
- 都快写完了, 发现好像之前已经解释过了
7. gcold capacity
-
命令
>jstat -gcoldcapacity 18436 OGCMN OGCMX OGC OC YGC FGC FGCT GCT 699392.0 11173888.0 455168.0 455168.0 3 1 0.017 0.042
-
解释
- OGCMN
- 老年代 初始大小
- OGCMX
- 老年代 最大大小
- OGC
- 老年区 当前容量
- OC
- 老年区 当前容量?
- OGCMN
-
疑问
- old space 和 old generation 是一个东西吗?
- 这个我目前还不能确定
- 但是 OGC 和 OC 这俩大多数时候, 是一样的
- old space 和 old generation 是一个东西吗?
-
后续
- 其实, 还有 一些其他的选项
- 比如 new 也有 gc 和 capacity 类似的选项
- 但是很多东西其实都大同小异, 内容上差不太多, 所以我就不介绍了
- 其实, 还有 一些其他的选项
ps
-
ref
- jstat
- 官网
- jstat命令详解---JVM的统计监测工具
- 另一篇中文描述
- Java 8的元空间(metaspace)
- metaspace 的简介
- JVM之GC监控
- 虽然有点 文不对题
- 但是 jstat 的命令行整理的还挺好
- 虽然有点 文不对题
- jstat
-
后续问题
- unload
- 编译类型
- jvm 内存模型
- old generation 和 old space 的关系
- 具体的优化思路
- jstatd 是个类似的命令行工具, 不过它本质上是个 rmi 服务, 这块如果以后需要, 就去看看