当前位置: 首页 > news >正文

JVM学习日记(十五)Day15——性能监控与调优(二)

好了我们这一篇继续来说命令行监控指令,上一篇说了4个比较重要的指令,其中用的比较多的也就是jstat和jmap了。

jhat:堆转储分析工具

他是JDK自带的分析工具,分析我们上一篇说的jmap转存的内存快照,​​内置了一个微型的HTTP服务器提供Web界面浏览分析结果(默认端口是7000),帮助识别内存泄漏和大对象,​同时支持OQL(Object Query Language)查询,但是已经在JDK9中被删除了,因为官方推荐使用VissualVM。

#基本语法
jhat [options] <heap-dump-file>#基本用法
# 分析堆转储文件并在7000端口启动服务
jhat heap.hprof# 访问分析结果
http://localhost:7000
参数说明示例
-stack false关闭对象分配调用栈跟踪jhat -stack false heap.hprof
-refs false关闭对象引用跟踪jhat -refs false heap.hprof
-port <port>指定HTTP服务器端口(默认7000)jhat -port 8000 heap.hprof
-exclude <file>指定排除文件(包含排除的类名)jhat -exclude exclude.txt heap.hprof
-baseline <file>指定基准堆转储(用于比较)jhat -baseline base.hprof heap.hprof
-debug <int>设置调试级别(0-2)jhat -debug 1 heap.hprof
-version显示版本信息jhat -version
-h/-help显示帮助信息jhat -help

 这个表示就已经启动成功了,可以去浏览器的http://localhost:8000/进行访问,这边建议小伙伴自己去尝试查看,知道这个东西就可以了,后面我们还是使用GUI图形界面去分析的,因为这个会更加的直观的。

jstack:生成 Java 进程的线程快照

我们上篇说到了jamp的堆快照,这里又有个可以查看线程的快照,因为程序出现卡顿不一定是堆堆问题嘛,也可能是线程的问题,jstack获取线程快照​:显示所有 Java 线程的调用栈信息,​诊断死锁​:自动检测并报告死锁线程,分析高 CPU 占用​:结合 top 或 jps 定位问题线程,排查线程阻塞​:识别等待资源或锁的线程。

#基本语法
jstack [options] <pid>
参数作用示例
-F强制生成线程转储(当进程挂起时使用)jstack -F 1234
-l显示额外锁信息(包含同步器和 java.util.concurrent 锁)jstack -l 1234
-m混合模式(显示 Java 和本地方法栈)jstack -m 1234
-h/-help显示帮助信息jstack -help

 这里来说一下区别,和jmap不同的就是他不会要求生成文件然后再分析,而是直接把内容打印到控制台,当然也是可以存文件的,这个文件就是普通的txt文件不需要其他命令或者工具辅助查看了。

jstack -F 1234 > thread_dump.txt
#其实所有的输出都可以用这种方式存到指定的文件
#这个就是基本信息了
2025-08-01 17:13:34 //快照时间
Full thread dump Java HotSpot(TM) 64-Bit Server VM (21.0.5+9-LTS-239 mixed mode, emulated-client, sharing): //虚拟机信息Threads class SMR info: //一共30个线程,线程的地址如下
_java_thread_list=0x0000600002111ac0, length=30, elements={
0x0000000127010a00, 0x0000000127011200, 0x0000000127011a00, 0x000000011680f600,
0x000000011680d000, 0x000000011680d800, 0x000000011680aa00, 0x00000001268b2c00,
0x00000001269abc00, 0x0000000117102800, 0x0000000126b09200, 0x0000000127333c00,
0x0000000126b1c000, 0x000000012723ec00, 0x0000000117200e00, 0x0000000126b0e000,
0x0000000117008e00, 0x000000012734f000, 0x000000012734f800, 0x0000000127346200,
0x0000000127346a00, 0x000000011721b800, 0x0000000126b36c00, 0x0000000126b3ec00,
0x0000000126b3f400, 0x0000000126b3fc00, 0x0000000127347200, 0x0000000126b40400,
0x0000000127344600, 0x0000000126820000
}"Reference Handler" #9 [32259] daemon prio=10 os_prio=31 cpu=1.76ms elapsed=141885.62s tid=0x0000000127010a00 nid=32259 waiting on condition  [0x000000016ec6e000]
#"Reference Handler"​​:线程名称
​​#9​:线程序号(JVM内部编号)
#​​[32259]​​:原生线程ID(Native Thread ID)
#​daemon​:这是一个守护线程(非用户线程)
​#prio=10​:Java线程优先级(1-10)
​#os_prio=31​:操作系统线程优先级
​#cpu=1.76ms​:该线程累计使用的CPU时间
​#elapsed=141885.62s​:线程已运行的时间(秒)
​#tid=0x0000000127010a00​:Java线程ID(内存地址)
#​nid=32259​:对应的操作系统线程ID(Native ID)
​#waiting on condition​:线程当前状态
​​#[0x000000016ec6e000]​​:线程栈的起始地址java.lang.Thread.State: RUNNABLE//运行状态at java.lang.ref.Reference.waitForReferencePendingList(java.base@21.0.5/Native Method)at java.lang.ref.Reference.processPendingReferences(java.base@21.0.5/Reference.java:246)at java.lang.ref.Reference$ReferenceHandler.run(java.base@21.0.5/Reference.java:208)

线程状态(Thread.State)

  • RUNNABLE​:线程正在执行或准备执行
  • WAITING​:线程等待某个条件(通常需要唤醒)
  • BLOCKED​:线程等待获取锁
  • TIMED_WAITING​:线程在指定时间内等待

这个就是jstack的示例,这里说一下什么是 daemon​:守护线程(JVM退出时不等待这些线程)什么是非daemon​:用户线程(JVM会等待这些线程结束),简单来说守护线程就是系统后台线程比如日志监控、垃圾回收等。

jcmd:多功能命令行工具

怎么说呢这哥们就是一个缝合怪,除了不能替代jstat其余的基本上都可以替代了,感觉前面讲的是不是有点多余了。

jcmd [options] <pid|main class> <command> [arguments]
部分含义是否必须示例
jcmd命令本身必须jcmd
[options]全局选项可选-l-f
<pid|main class>目标进程标识必须1234 或 com.example.MyApp
<command>要执行的诊断命令可选Thread.printGC.heap_dump
[arguments]命令参数可选filename=/tmp/dump.hprof
命令作用示例
VM.flags查看JVM参数jcmd 1234 VM.flags
VM.system_properties查看系统属性jcmd 1234 VM.system_properties
VM.uptime显示JVM运行时间jcmd 1234 VM.uptime
VM.version显示JVM版本jcmd 1234 VM.version
Thread.print生成线程转储jcmd 1234 Thread.print
GC.class_histogram显示类直方图jcmd 1234 GC.class_histogram
GC.heap_dump生成堆转储文件jcmd 1234 GC.heap_dump /path/to/dump.hprof
GC.run_finalization强制执行finalizejcmd 1234 GC.run_finalization
GC.run显式触发GCjcmd 1234 GC.run
JFR.start开始JFR记录jcmd 1234 JFR.start name=myrec settings=profile
JFR.dump导出JFR记录jcmd 1234 JFR.dump name=myrec filename=rec.jfr
JFR.stop停止JFR记录jcmd 1234 JFR.stop name=myrec
VM.native_memory本地内存统计jcmd 1234 VM.native_memory summary

 突然感觉这个命令有点复杂了有木有,主包这边就不演示了,这么多参数和命令又点头疼,具体使用什么命令还是要看小伙伴自己和使用的场景,有兴趣的小伙伴自己去试试看吧。

jstatd:远程监控工具

作用就是为远程主机提供 JVM 监控数据,通过 RMI 协议提供监控数据,可同时监控多个 Java 进程,支持 VisualVM、JConsole 等工具连接,这个咱们就简单说一下就好了,因为大多数生成环境是不允许的,多开一个端口都是有风险的。

#基本语法
jstatd [options]
#实例
jstatd -J-Djava.security.policy=jstatd.policy -p 3333
参数作用示例
-p <port>指定 RMI 注册端口jstatd -p 1099
-n <name>指定 RMI 注册名称jstatd -n MyJstatd
-J<option>传递参数给 JVMjstatd -J-Djava.security.policy=my.policy
-nr不创建 RMI 注册表jstatd -nr
-r <port>指定 RMI 注册表端口jstatd -r 1099
-h/-help显示帮助信息jstatd -h

 总结

本篇把剩下的命令行已经全部介绍完了,下一篇讲讲GUI图形界面,大家好好练习命令吧。

http://www.xdnf.cn/news/1237501.html

相关文章:

  • IO流-对象流
  • 回归的wry
  • 前后端交流
  • 电路原理图绘制专业实战教程2
  • Nginx负载均衡配置
  • 6. 平台总线
  • 跨语言模型中的翻译任务:XLM-RoBERTa在翻译任务中的应用
  • Compose笔记(四十一)--ExtendedFloatingActionButton
  • 有限元方法中的数值技术:三角矩阵求解
  • Redis面试精讲 Day 10:Redis数据结构底层实现原理
  • 【AI论文】Rep-MTL:释放表征级任务显著性在多任务学习中的潜力
  • 介绍JAVA语言、介绍greenfoot 工具
  • 数据结构中使用到的C语言
  • golang的包和闭包
  • Python 小数据池(Small Object Pool)详解
  • 使用AndroidStudio调试Framework源码
  • 关于域名的级别
  • Linux环境下使用Docker搭建多服务环境
  • Apache Shenyu 本地启动及快速入门
  • Flutter开发 dart异步
  • 动态置信度调优实战:YOLOv11多目标追踪精度跃迁方案(附完整代码)
  • 基于springboot的在线考试系统/考试信息管理平台
  • 生成式人工智能展望报告-欧盟-04-社会影响与挑战
  • trace-cmd记录线程被中断打断的时间
  • Java 实现poi方式读取word文件内容
  • 编译旧版本的electron内核
  • VisualStudio的一些开发经验
  • 能表示旋转的矩阵是一个流形吗?
  • C++与Go的匿名函数编程区别对比
  • 吴恩达【prompt提示词工程】学习笔记