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

零基础学习性能测试第二章-JVM如何监控

目录

      • 一、JVM监控核心指标(先记这6个)
      • 二、必备监控工具与速查命令
        • 1. **实时监控三件套**
        • 2. **GC日志配置(必须开启!)**
      • 三、4种内存泄漏快速定位法
        • 场景:堆内存持续增长不释放
      • 四、GC性能调优实战
        • 高频Full GC问题排查
      • 五、线程问题定位技巧
        • 1. **线程数暴涨**
        • 2. **死锁检测**
        • 3. **CPU飙高分析**
      • 六、生产级监控方案(Prometheus + Grafana)
        • 1. 监控体系搭建
        • 2. 关键Dashboard指标
        • 3. 告警规则示例
      • 七、性能测试JVM监控SOP
      • 八、避坑指南(血泪经验)

以下是专为零基础设计的JVM监控实战指南,聚焦关键指标、常用工具和快速定位问题的方法,可直接应用于性能测试工作:


一、JVM监控核心指标(先记这6个)

指标健康标准异常表现排查工具
堆内存使用率Old Gen < 70%持续增长不释放 → 内存泄漏jstat -gc
Full GC频率0次/小时频繁Full GC (>1次/分钟)GC日志分析
Full GC耗时< 1秒> 3秒 → STW卡顿jstat -gcutil
Young GC耗时< 100ms> 200ms → 年轻代配置问题VisualVM
线程数< 最大线程数80%线程数暴涨 → 线程泄漏jstack
CPU占用单进程 < 70%持续100% → 死循环/锁竞争top + jstack

二、必备监控工具与速查命令

1. 实时监控三件套
# 1. 监控GC状态 (每2秒刷新)
jstat -gcutil <PID> 2000# 输出解读:
# S0  S1  E   O    M     CCS    YGC   YGCT   FGC  FGCT   GCT
# 0.0 0.0 65.0 25.0 95.0  90.0   100   1.5    5    0.8   2.3
# ▶️ E: Eden区使用率 | O: 老年代 | FGC: Full GC次数 | FGCT: Full GC总耗时# 2. 查看JVM参数 (关键配置)
jcmd <PID> VM.flags# 3. 生成线程快照 (分析死锁/阻塞)
jstack <PID> > thread_dump.txt
2. GC日志配置(必须开启!)
// JDK 8及之前
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/path/to/gc.log// JDK 11+ (推荐)
-Xlog:gc*:file=/path/to/gc.log:time:filecount=0

日志分析工具:

  • GCeasy(在线分析)
  • grep "Full GC" gc.log(手动检查Full GC)

三、4种内存泄漏快速定位法

场景:堆内存持续增长不释放
  1. 步骤1:确认泄漏

    jmap -heap <PID> | grep "used"  # 观察Old Gen使用趋势
    
  2. 步骤2:生成堆转储

    jmap -dump:live,format=b,file=heapdump.hprof <PID>
    
  3. 步骤3:分析堆快照

    • 工具:Eclipse MAT / VisualVM
    • 定位技巧:
      • 查找 Retained Heap 最大的对象
      • 检查 Unreachable Objects(不可达对象)
      • 查看 Dominator Tree(支配树)
  4. 常见泄漏模式:

    内存泄漏
    静态集合未清理
    线程池未销毁
    缓存未设TTL
    资源未关闭

四、GC性能调优实战

高频Full GC问题排查
# 1. 检查GC原因
grep -A 5 "Full GC" gc.log# 典型原因:
# - "Allocation Failure"   -> Eden区不足
# - "Metadata GC Threshold" -> 元空间不足
# - "System.gc()"          -> 代码调用System.gc()# 2. 优化方案
| 问题现象                | 参数调整                  |
|------------------------|--------------------------|
| Young GC频繁           | -Xmn增加年轻代大小        |
| Full GC后堆内存未释放   | -XX:+UseCMSCompactAtFullCollection |
| CMS GC失败             | -XX:CMSInitiatingOccupancyFraction=70 |
| G1混合GC耗时过长        | -XX:G1MixedGCLiveThresholdPercent=85 |

五、线程问题定位技巧

1. 线程数暴涨
# 统计线程数
ps -eLf | grep java | wc -l# 分析线程类型
jstack <PID> | grep "java.lang.Thread.State" | sort | uniq -c
2. 死锁检测
jstack <PID> | grep -A 10 "deadlock"
3. CPU飙高分析
# 1. 找高CPU线程
top -H -p <PID>  # 记录线程ID(十进制)# 2. 线程ID转十六进制
printf "%x\n" 12345  # 输出:3039# 3. jstack中搜索nid=0x3039
jstack <PID> | grep -A 20 "nid=0x3039"

六、生产级监控方案(Prometheus + Grafana)

1. 监控体系搭建
JMX
Metrics
Dashboard
JVM
JMX Exporter
Prometheus
Grafana
2. 关键Dashboard指标
  • 内存:Heap/Non-Heap Memory Usage
  • GC:GC Pause Duration, GC Count
  • 线程:Thread States, Deadlock Detection
  • 类加载:Loaded Classes Count
3. 告警规则示例
# Prometheus告警规则
- alert: FullGCTooFrequentexpr: increase(jvm_gc_pause_seconds_count{gc="PS MarkSweep"}[1m]) > 2for: 5mlabels:severity: criticalannotations:summary: "Full GC频繁 (实例 {{ $labels.instance }})"

七、性能测试JVM监控SOP

  1. 压测前准备

    # 开启GC日志
    java -Xlog:gc*:file=gc.log -jar app.jar# 添加OOM自动dump
    -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp
    
  2. 压测中监控

    # 实时看板
    jstat -gcutil <PID> 1000  # 每秒刷新
    jcmd <PID> Thread.print    # 定时抓线程
    
  3. 压测后分析

    # 1. GC分析
    cat gc.log | grep "Full GC" | wc -l  # 统计Full GC次数# 2. 内存泄漏检查
    jmap -histo:live <PID> | head -20  # 对象直方图# 3. 生成报告
    echo "=== JVM健康报告 ==="
    echo "Full GC次数: $(grep 'Full GC' gc.log | wc -l)"
    echo "最大堆内存: $(jstat -gccapacity <PID> | awk '{print $4/1024"MB"}')"
    

八、避坑指南(血泪经验)

  1. 元空间溢出
    -XX:MaxMetaspaceSize=256m# 默认无限制需手动设置

  2. 堆外内存泄漏
    监控 Native Memory Tracking (NMT)

    -XX:NativeMemoryTracking=detail
    jcmd <PID> VM.native_memory summary
    
  3. G1并发模式失败
    增加 -XX:ConcGCThreads或降低 -XX:InitiatingHeapOccupancyPercent

  4. 线程池耗尽
    jstack中搜索 "pool-1-thread"查看阻塞栈


终极命令:一键式JVM健康检查

#!/bin/bash
PID=$(jps | grep YourApp | awk '{print $1}')
echo "===== JVM健康检查 ====="
echo "1. GC状态:"
jstat -gcutil $PID 1000 3
echo "2. 堆内存:"
jmap -heap $PID | grep -E "Heap Usage|New Generation"
echo "3. 线程快照:"
jstack $PID | grep "java.lang.Thread.State" | sort | uniq -c

掌握这些技能,你可以在10分钟内完成JVM基础问题定位,有效支撑性能测试工作。记住核心口诀:
“内存泄漏查堆dump,GC瓶颈看日志,线程问题抓jstack,生产监控上Prometheus”

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

相关文章:

  • Android系统5层架构
  • 【论文笔记】OccluGaussian解决大场景重建中的区域遮挡问题
  • 5G NR PDCCH之信道编码
  • c#:管理TCP服务端发送数据为非16进制
  • 4、ubuntu | dify创建知识库 | 上市公司个股研报知识库
  • Python知识点4-嵌套循环break和continue使用死循环
  • 统计与大数据分析和数字经济:专业选择指南
  • LP-MSPM0G3507学习--07定时器之二定时节拍
  • 使用“桥接模式“,实现跨平台绘图或多类型消息发送机制
  • SpringBoot的介绍和项目搭建
  • 【C语言】字符串与字符函数详解(上)
  • C++ 详谈继承体系下的构造函数和析构函数
  • k8s:离线添加集群节点的相关组件安装与升级
  • GeoServer 信息泄漏漏洞复现(CVE-2025-27505)
  • 周志华《机器学习导论》第11章 特征选择与稀疏学习
  • 机器学习-数据预处理
  • 闲庭信步使用图像验证平台加速FPGA的开发:第二十六课——正弦波DDS的FPGA实现
  • leetcode75【经典动态规划】之:最长公共子序列
  • nginx源码解读-------整体架构
  • 30天打牢数模基础-LightGBM讲解
  • 网络地址和主机地址之间进行转换的类
  • springboot电影推荐网站—计算机毕业设计源码—30760
  • 在Ubutu22系统上面离线安装Go语言环境【教程】
  • 【开源项目】基于RuoYi-Vue-Plus的开源进销存管理系统
  • Spring之AOP面向切面编程详解
  • 软件工程学概述:从危机到系统化工程的演进之路
  • MySQL详解三
  • Java 字符集(Charset)详解:从编码基础到实战应用,彻底掌握字符处理核心机制
  • 文件编码概念|文件的读取操作|文件读取的课后练习讲解
  • 数据治理,治的是什么?