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

Java 故障分析与性能调优命令详解(含案例)

一、JVM 进程与基础信息查询

1. jps - 定位 Java 进程

功能:快速列出当前系统中所有 Java 进程的 PID 和主类名,是后续所有命令的基础。语法jps [选项],常用选项-l显示主类完整路径,-v显示 JVM 启动参数。案例:假设服务器运行着一个 Spring Boot 应用和一个普通 Java 程序,执行jps -l后输出:

1234 org.springframework.boot.loader.JarLauncher  # Spring Boot应用,PID=1234
5678 com.example.DemoApplication                  # 普通Java程序,PID=5678
7901 sun.tools.jps.Jps                           # jps自身进程

通过该命令可快速获取目标应用的 PID(如 1234),用于后续排查。

2. jinfo - 查看 JVM 配置

功能:查看指定 Java 进程的 JVM 参数(如堆大小、GC 算法)和系统属性。语法

  • jinfo [PID]:查看所有配置和属性。
  • jinfo -flags [PID]:仅查看 JVM 启动参数(关键)。
  • jinfo -sysprops [PID]:仅查看系统属性。

案例:排查 “堆内存溢出” 前兆时,先确认堆配置是否合理。执行jinfo -flags 1234

Attaching to process ID 1234, please wait...
Debugger attached successfully.
Server compiler detected.
VM Flags:
-XX:InitialHeapSize=536870912  # 初始堆大小512M
-XX:MaxHeapSize=1073741824     # 最大堆大小1G
-XX:MetaspaceSize=268435456    # 元空间初始大小256M
-XX:+UseG1GC                   # 使用G1垃圾收集器
-XX:+HeapDumpOnOutOfMemoryError # OOM时自动生成堆快照

若发现MaxHeapSize过小(如仅 256M),且应用内存需求高,可判断堆配置不合理,需调整启动参数-Xmx

二、内存问题排查(OOM、内存泄漏)

1. jstat - 实时监控内存与 GC

功能:持续采集 JVM 内存区域(Eden、Survivor、Old、Metaspace)使用情况及 GC 统计,快速定位内存异常趋势。核心语法jstat -[选项] [PID] [间隔时间(ms)] [采集次数]常用选项:

  • -gc:监控堆内存各区域使用量、GC 次数、GC 耗时。
  • -gcutil:以百分比显示堆内存使用情况,更直观。

案例:监控 Spring Boot 应用(PID=1234)的 GC 情况,每 1 秒采集 1 次,共 10 次:执行jstat -gcutil 1234 1000 10,输出:

  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT0.00  50.00  95.23  88.67  92.10  89.32   125    6.234     8    15.678   21.9120.00  50.00  98.76  89.12  92.10  89.32   126    6.310     8    15.678   21.9880.00   0.00   3.45  90.05  92.10  89.32   127    6.385     9    16.890   23.275

关键指标解读

  • S0/S1:Survivor 区使用率,若频繁切换非 0,说明年轻代回收正常。
  • E:Eden 区使用率,若持续接近 100%,说明年轻代对象创建快,回收频繁。
  • O:老年代使用率,若持续增长至 90% 以上,可能面临 OOM 风险。
  • FGC:Full GC 次数,案例中 10 秒内 FGC 从 8 次增至 9 次,且FGCT(Full GC 耗时)增加 1.2 秒,说明老年代回收压力大,可能存在内存泄漏或堆配置不足。

2. jmap + jhat - 堆快照分析

功能

  • jmap:生成堆转储文件(记录堆中所有对象的类型、数量、大小、引用关系),是排查内存泄漏的核心工具。
  • jhat:离线分析堆转储文件,通过 Web 界面展示对象分布。

语法

  1. 生成堆快照:jmap -dump:format=b,file=heapdump.hprof [PID]format=b表示二进制格式)。
  2. 分析快照:jhat heapdump.hprof,启动 Web 服务(默认端口 7000),浏览器访问http://localhost:7000

案例:排查 “应用运行 2 天后 OOM” 问题

  1. 当应用老年代使用率达 90% 时,执行jmap -dump:format=b,file=app_heap.hprof 1234,生成堆快照。
  2. 执行jhat app_heap.hprof,浏览器打开后查看 “Show heap histogram”(堆直方图),发现com.example.UserSession类的对象数量达 10 万 +,且每个对象占用 1KB 内存,总占用 100MB 以上。
  3. 进一步查看 “Find object by id”,追溯引用关系,发现SessionManager类中存在一个静态Map,未及时移除过期的UserSession对象,导致对象持续堆积到老年代,最终引发 OOM。解决方案:将Map替换为带过期策略的ConcurrentHashMap或使用Guava Cache

三、线程问题排查(死锁、线程阻塞)

1. jstack - 线程栈快照分析

功能:生成线程栈快照,展示每个线程的执行状态(RUNNABLE、BLOCKED、WAITING)、调用栈,用于排查死锁、线程阻塞、长时间运行的线程。语法jstack [选项] [PID],常用选项-F(强制生成快照,适用于进程无响应时)。

案例 1:排查死锁执行jstack 1234,输出中若包含 “Found one Java-level deadlock”,则明确存在死锁:

Found one Java-level deadlock:
=============================
"Thread-1":waiting to lock monitor 0x00007f8a1203d000 (object 0x000000076b8e4260, a java.lang.Object),which is held by "Thread-0"
"Thread-0":waiting to lock monitor 0x00007f8a1203f800 (object 0x000000076b8e4270, a java.lang.Object),which is held by "Thread-1"

原因:Thread-0 持有锁 A,等待锁 B;Thread-1 持有锁 B,等待锁 A,形成循环等待。解决方案:统一线程获取锁的顺序(如先锁 A 再锁 B)。

案例 2:排查线程阻塞执行jstack 1234,发现多个线程状态为BLOCKED

"http-nio-8080-exec-5" #23 daemon prio=5 os_prio=0 tid=0x00007f8a10032000 nid=0x5a waiting for monitor entry [0x00007f8a08a7e000]java.lang.Thread.State: BLOCKED (on object monitor)at com.example.OrderService.createOrder(OrderService.java:45)- waiting to lock <0x000000076b901000> (a com.example.OrderService)at com.example.OrderController.addOrder(OrderController.java:28)

分析OrderService.createOrder方法使用synchronized修饰,且当前有线程长时间持有锁(如执行慢 SQL),导致后续请求线程阻塞。解决方案:优化锁内逻辑(如将慢 SQL 移至锁外),或改用ReentrantLock设置超时时间。

2. top + jstack - 定位高 CPU 线程

场景:应用 CPU 使用率突然飙升至 100%,需找到具体耗 CPU 的线程和代码。步骤

  1. 执行top -Hp 1234-H显示线程级 CPU 占用),找到 CPU 使用率最高的线程 PID(如 12345)。
  2. 将线程 PID 转换为 16 进制(因为 jstack 输出的线程 ID 是 16 进制):printf "%x\n" 12345,得到3039
  3. 执行jstack 1234 | grep -A 20 3039,查看该线程的调用栈:
"Thread-8" #35 prio=5 os_prio=0 tid=0x00007f8a10045000 nid=0x3039 runnable [0x00007f8a0857a000]java.lang.Thread.State: RUNNABLEat com.example.DataProcessor.calculate(DataProcessor.java:68)at com.example.DataProcessor.run(DataProcessor.java:32)at java.lang.Thread.run(Thread.java:748)

分析DataProcessor.calculate方法第 68 行存在死循环(如while(true)未加退出条件),导致线程持续占用 CPU。解决方案:修复死循环逻辑,添加合理的退出条件。

四、性能调优辅助工具

1. jvisualvm - 图形化综合分析

功能:JDK 自带的图形化工具,集成了 jps、jstat、jmap、jstack 的功能,支持实时监控、堆分析、线程分析、性能采样,适合开发环境快速排查。使用步骤

  1. 命令行输入jvisualvm启动工具。
  2. 在左侧 “本地” 节点下找到目标进程(如 1234),双击连接。
  3. 关键功能:
    • 监控:实时查看 CPU、内存、类加载、线程数量变化。
    • 线程:查看线程状态,点击 “检测死锁” 可自动识别死锁。
    • 抽样器:选择 “CPU 抽样”,运行一段时间后查看 “热点方法”,快速定位耗时最长的代码(如频繁调用的工具类方法)。

案例:调优接口响应慢通过 “CPU 抽样” 发现UserService.queryUser方法耗时占比达 60%,进一步查看代码,发现该方法每次查询都新建数据库连接,未使用连接池。解决方案:集成数据库连接池(如 HikariCP),复用连接,接口响应时间从 500ms 降至 50ms。

2. Arthas - 线上诊断神器

功能:阿里开源的在线诊断工具,无需重启应用即可实现反编译、线程分析、性能采样、堆快照等功能,适合生产环境排查。常用命令案例

  1. dashboard:实时查看进程概览,包括 CPU、内存、GC、线程数:
Arthas dashboard
ID     NAME                   GROUP          PRIORITY  STATE    %CPU    TIME   INTERRUPTED  DAEMON
123    http-nio-8080-exec-1   main           5         RUNNABLE 30.0    0:12   false        true
456    GC task thread#0 (G1)  system         -1        RUNNABLE 15.0    0:08   false        true
  1. thread -b:快速定位阻塞线程的源头:
thread -b
Found one blocked thread:
"http-nio-8080-exec-5" Id=23 BLOCKED on com.example.OrderService@6b8e4260 owned by "http-nio-8080-exec-3" Id=21at com.example.OrderService.createOrder(OrderService.java:45)- blocked on com.example.OrderService@6b8e4260at com.example.OrderController.addOrder(OrderController.java:28)
  1. profiler start/stop:CPU 性能采样,生成火焰图(需安装 graphviz),直观展示方法调用耗时占比,快速定位性能瓶颈。

http://www.dtcms.com/a/482953.html

相关文章:

  • 【Pytorch】激活函数 Loss 梯度 超详细文本笔记
  • 不同材质金冠钳的力学性能及其对修复体就位影响研究
  • vs2015做网站的后端个人怎么做百度竞价
  • 微信小程序入门学习教程,从入门到精通,项目实战:美妆商城小程序 —— 知识点详解与案例代码 (18)
  • 微信小程序添加水印功能
  • 02_ES索引规范kibana
  • 购物网站建设模板图片价格低的跑车
  • LeetCode hot100:049 字母异位词分组:两种解法的深度解析
  • 网站建设业务前景政务信息网站建设制度
  • 使用C#写微信小程序后端——电商微信小程序
  • C++——vector容器、动态容器
  • C++ 类与对象(下篇)笔记整理
  • 重庆建站服务商漳浦网站开发
  • 深入浅出理解电感:从理论到实践的电路“惯性”元件
  • 分布式事务:基于MQ事务的解决方案详解
  • 无信息先验:贝叶斯分析中的客观基准
  • 公司官网备案流程mysql优化 wordpress
  • 网站建设员课程注册网页版
  • 瑞莎星瑞(Radxa Orion O6) 基于 Android OS 使用 NPU的图片模糊查找APP 开发
  • 户外商品网站制作长沙网站建设的公司
  • 安卓13_ROM修改定制化-----ROM解打包 修改 讲解 导读篇
  • 网站设计亮点望野亭
  • RTC时钟原理
  • STM32运行原理深度解析:从软件到硬件的神奇之旅
  • OpenCV(十一):色彩空间转换
  • 广州安全教育平台网宁波网站seo哪家好
  • 家装网站自己做的平面设计常用网站
  • Three.js轨道控制器完全指南(OrbitControls与TrackballControls)
  • 服务器数据恢复—硬盘黄灯预警,RAID5阵列数据如何恢复?
  • CATIA 转换为 3DXML 全流程:迪威模型网在线转换和本地方转换方法指南