【大白话说Java面试题 第68题】【JVM篇】第28题:对于 JDK 自带的监控和性能分析工具用过哪些?一般你怎么用的?

📌 PDF :大白话说Java面试题 --- 02-JVM篇

第28题:对于 JDK 自带的监控和性能分析工具用过哪些?一般你怎么用的

📚 回答:

  • 核心考点
    大厂面试要求熟练掌握 JDK 自带工具 ,并能结合场景说明使用时机、命令参数、结果解读。不能只会罗列工具名称。

1. 工具全景图
工具 核心用途 是否需要目标进程 是否STW
jps 列出 Java 进程 PID
jinfo 查看/修改 JVM 参数
jstat GC 和内存区域实时统计
jmap 堆内存快照(dump) 是(严重)
jstack 线程堆栈快照 否(但可能略慢)
jcmd 多功能综合工具(JDK 7+) 部分操作会
VisualVM 图形化综合监控 是(可本地/远程) 采样模式不影响

2. 各工具典型用法(附命令)

2.1 jps:定位目标进程

bash 复制代码
jps -l          # 显示完整主类名
jps -v          # 显示传递给 JVM 的参数

场景:启动分析前第一步,拿到 PID。


2.2 jstat:实时监控 GC(最常用)

bash 复制代码
# 每1秒打印一次,共打印10次
jstat -gcutil <PID> 1000 10

# 输出列解读:
# S0/S1: Survivor 使用率
# E: Eden 使用率
# O: 老年代使用率
# M: 元空间使用率
# YGC/YGCT: Young GC 次数/总耗时
# FGC/FGCT: Full GC 次数/总耗时
# GCT: GC 总耗时

实战判断

  • YGC 每分钟超过60次 → 年轻代太小
  • FGC 每小时 >1 次 → 需排查(除非元空间/堆合理调优后仍存)
  • GCT / 运行时长 > 10% → GC 已严重影响吞吐

2.3 jmap:堆内存快照(谨慎使用)

bash 复制代码
# 生成 dump 文件(会触发 Full GC,生产需低峰期)
jmap -dump:live,format=b,file=/tmp/heap.hprof <PID>

# 查看对象统计(不会 dump 大文件,但仍会 STW)
jmap -histo:live <PID> | head -30

⚠️ 重要

  • -dump:live 会先触发 Full GC,STW 时间可能达数秒甚至分钟
  • 生产环境优先用 -XX:+HeapDumpOnOutOfMemoryError 自动 dump
  • 高并发系统用 jcmd <PID> GC.heap_dump /path/dump.hprof(底层同 jmap,依然 STW)

分析 dump :用 MAT(Eclipse Memory Analyzer)VisualVM 查看 Leak Suspects、Dominator Tree。


2.4 jstack:线程快照(无痛)

bash 复制代码
# 导出线程栈
jstack -l <PID> > thread.dump

# 快速统计线程状态
grep "java.lang.Thread.State" thread.dump | sort | uniq -c

经典用法

  • CPU 飙高top -H -p <PID> 找线程 ID(十进制的) → printf "%x\n" <十进制tid> → 在 jstack 输出中搜索十六进制 tid
  • 死锁 :jstack 输出末尾会直接报告 "Found one Java-level deadlock"
  • 接口超时:连续多次打印 jstack,对比 WAITING/BLOCKED 线程是否一直卡在同一位置

2.5 jinfo:查看运行时参数

bash 复制代码
# 查看所有可设置参数及当前值
jinfo -flags <PID>

# 查看单个参数
jinfo -flag UseG1GC <PID>

# 动态修改(部分参数支持)
jinfo -flag +HeapDumpOnOutOfMemoryError <PID>

场景 :线上验证 -Xmx 是否生效、某个 GC 参数是否真的被打开。


2.6 jcmd:新一代瑞士军刀(JDK 7+ 推荐)

bash 复制代码
# 列出所有可执行命令
jcmd <PID> help

# 查看 JVM 运行时参数(替代 jinfo -flags)
jcmd <PID> VM.flags

# 手动触发 GC(慎用,仅测试)
jcmd <PID> GC.run

# 获取系统属性
jcmd <PID> VM.system_properties

# 获取线程栈(同 jstack)
jcmd <PID> Thread.print

# 生成 heap dump
jcmd <PID> GC.heap_dump /tmp/dump.hprof

# 查看 Native 内存(诊断直接内存/堆外)
jcmd <PID> VM.native_memory summary

优势:统一入口,输出结构更清晰,部分操作比 jmap 更安全。


2.7 VisualVM:图形化利器

连接方式

  • 本地:自动检测本机 Java 进程
  • 远程 :通过 JMX(需开启 -Dcom.sun.management.jmxremote

常用 Tab

  • Monitor:CPU/堆/元空间/类/线程 实时曲线
  • Threads:线程状态及堆栈,可检测死锁
  • Sampler:CPU 采样 → 热点方法;内存采样 → 对象分配统计
  • Profiler(需插件):更精确但开销大,生产慎用

生产远程连接示例(JMX 参数):

bash 复制代码
-Dcom.sun.management.jmxremote=true \
-Dcom.sun.management.jmxremote.port=9999 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false

3. 实战案例:生产 Full GC 频繁排查

现象 :服务 GC 报警,FGC 每小时 12 次,老年代占用率 95% 不降。

步骤

步骤 工具 命令 发现
1 jps jps -l PID 12345
2 jstat jstat -gcutil 12345 1000 O(老年代)始终 98%,FGC 持续增长
3 jmap(低峰期) `jmap -histo:live 12345 head -20`
4 jstack jstack 12345 > t.dump 大量线程在 SessionCache.put 等待锁
5 定位代码 结合业务日志 缓存未设过期时间,且未限制最大容量
6 修复 代码:改用 Caffeine 缓存 + TTL 上线后 FGC 降为 0

4. 面试官追问示例

Q1:jmap -histo:live 会触发 Full GC 吗?

A:live 参数会先执行一次 Full GC 再统计存活对象。生产环境慎用,优先用 jstat 看趋势或 Arthas heapdump

Q2:jstack 打印出的 BLOCKED 线程很多,一定有问题吗?

A:不一定。若 BLOCKED 是瞬时锁竞争且正常情况(如 synchronized 高并发),只要不持续堆积就正常。需多次打印确认是否一直卡在同一锁

Q3:远程连接 VisualVM 不安全怎么办?

A:生产禁止明文 JMX。替代方案:

  • jstat / jstack 本地执行后导出分析
  • 用 Arthas(阿里开源)隧道连接
  • 开启 JMX + SSL 认证(复杂)

Q4:jcmd 能完全替代 jmap 吗?

A:大部分可以。jcmd GC.heap_dumpjmap -dump,但 jcmd VM.native_memory 是 jmap 没有的功能。不过 jmap -histo 的快速对象统计,jcmd 没有直接等价命令。

Q5:生产环境不能安装任何额外工具,只有 JDK 自带,怎么排查?

A:就用 jps/jstat/jstack/jmap/jcmd 组合。例如:

  • CPU 高 → top -H -p PID + jstack
  • 内存泄漏 → jstat -gcutil 看 O 区持续增长 + jmap -dump:live(择低峰期)
  • GC 频繁 → jstat -gc 看明细

💡 面试官想要的满分总结

"日常问题排查,我按以下组合使用:

  • jps 找 PID
  • jstat -gcutil 看 GC 趋势,决定是否需要 dump
  • jstack 查线程阻塞/死锁/热点栈
  • jmap 只在低峰期或 OOM 后分析 dump
  • jcmd 作为统一入口,尤其 VM.native_memory 排查堆外内存
  • VisualVM 用于本地或开发环境做性能分析

核心原则:生产环境首选无侵入工具(jstat/jstack/jcmd 非 live 操作),jmap 务必审批后执行。"


觉得对您有帮助,麻烦 点点关注啦 ,您的关注是我创作的最大动力~ 🎯

相关推荐
青梅橘子皮1 小时前
Linux---冯诺伊曼体系结构,操作系统概况
java·linux·运维
学习,学习,在学习1 小时前
Qt 串口通讯架构
开发语言·c++·qt·架构·qt5
Hexian25801 小时前
SpringAI MCP
java·spring·ai
一条泥憨鱼1 小时前
深入理解2026AI最大公约数:Agent
开发语言·人工智能·ai·agent
苦逼的猿宝1 小时前
基于SpringBoot的旅游网站的设计与实现(源码+论文)
java·毕业设计·springboot·计算机毕业设计
刻BITTER1 小时前
Alpine.js + Chart.js 踩坑记:一次 Maximum Call Stack Exceeded 排查之旅
开发语言·javascript·ecmascript
郝学胜-神的一滴1 小时前
干货版《算法导论》05:从集合接口到排序
开发语言·数据结构·c++·程序人生·算法·排序
之歆1 小时前
Day15_JavaScript DOM 事件完全指南:从基础到实战(下)
开发语言·javascript·ecmascript
顾凌陵1 小时前
Python 数据可视化实战
开发语言·python·信息可视化