JVM 调优之 CPU 高占用问题

简介: jstack(Stack Trace for Java) 命令用于生成当前时刻的线程快照(一般称为 threaddump 文件)。

jstack 工具


jstack(Stack Trace for Java) 命令用于生成当前时刻的线程快照(一般称为 threaddump 文件)。


线程快照就是当前虚拟机每条线程正在执行的方法堆栈集合,生成线程快照的目的通常是定位线程出现长时间停顿的原因,如线程间死锁,死循环、请求外部资源导致的长时间挂起等,都是导致线程长时间停顿的原因。


线程出现停顿是通过 jstack 来查看各个线层呢的调用堆栈,就可以获知没有响应的线程到底在后台做什么,或者等待什么资源。


jstack 命令格式:


jstack [option] vmid


下面我们就开始实践,说下环境:jdk 1.8, 操作系统 ubantu 20.04


排查 CPU 高占用问题


我们先写一个简单的死循环程序,来模拟 CPU 高占用问题。


测试代码如下:


public class MathTest {
    public int compute() {
        int a = 1026;
        int b = 2018;
        return (a + b) * 10;
    }
    public static void main(String[] args) {
        MathTest math = new MathTest();
        //System.out.println(math.compute());
        while (true) {
            math.compute();
        }
    }
}


编译和执行命令如下:


// 编译
javac MathTest.java
// 后台执行
java MathTest &


核心步骤


  1. jps 打印 Java 进程(查看是否启动)


zhengsh@zhengsh:/opt/apps$ jps
4541 MathTest
4559 Jps


  1. top 命令,查询指定进程的线程信息,然后通过 shift + p 通过 cpu 占用排序


top -Hp 4541


结果如下:


image.png


找到高占用 cpu 的线程 id 4542


  1. 通过 pid 转化为 16 进制


printf "%x\n" 4542
11be


  1. 查询所在的后面 30 行


jstack 4541|grep 11be -A 30
// 显示结果如下:
"main" #1 prio=5 os_prio=0 tid=0x00007f8efc00a800 nid=0x11be runnable [0x00007f8f016a3000]
   java.lang.Thread.State: RUNNABLE
  at MathTest.main(MathTest.java:13)
"VM Thread" os_prio=0 tid=0x00007f8efc074000 nid=0x11c1 runnable 
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f8efc01f800 nid=0x11bf runnable 
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f8efc021000 nid=0x11c0 runnable 
"VM Periodic Task Thread" os_prio=0 tid=0x00007f8efc0d9000 nid=0x11c8 waiting on condition 
JNI global references: 5


我们可以查询到 MathTest 类 13 行正在运行,在回看代码:


image.png


这里是有死循环调用,导致 CPU 过高。问题找到,解决完毕。


参考资料


  • 《深入理解 JVM 虚拟机 第四版》周志明


相关文章
|
15天前
|
监控 Java 调度
探秘Java虚拟机(JVM)性能调优:技术要点与实战策略
【6月更文挑战第30天】**探索JVM性能调优:**关注堆内存配置(Xms, Xmx, XX:NewRatio, XX:SurvivorRatio),选择适合的垃圾收集器(如Parallel, CMS, G1),利用jstat, jmap等工具诊断,解决Full GC问题,实战中结合MAT分析内存泄露。调优是平衡内存占用、延迟和吞吐量的艺术,借助VisualVM等工具提升系统在高负载下的稳定性与效率。
31 1
|
17天前
|
监控 Java 测试技术
Java中的JVM调优技巧
Java中的JVM调优技巧
|
3天前
|
监控 算法 Java
深入探索Java虚拟机:性能监控与调优实践
在面对日益复杂的企业级应用时,Java虚拟机(JVM)的性能监控和调优显得尤为重要。本文将深入探讨JVM的内部机制,分析常见的性能瓶颈,并提供一系列针对性的调优策略。通过实际案例分析,我们将展示如何运用现代工具对JVM进行监控、诊断及优化,以提升Java应用的性能和稳定性。
|
5天前
|
缓存 Prometheus 监控
Java面试题:如何监控和优化JVM的内存使用?详细讲解内存调优的几种方法
Java面试题:如何监控和优化JVM的内存使用?详细讲解内存调优的几种方法
25 3
|
5天前
|
缓存 监控 算法
Java面试题:讨论JVM性能调优的常见方法和技巧。
Java面试题:讨论JVM性能调优的常见方法和技巧。
10 1
|
11天前
|
监控 算法 Java
JVM调优---堆溢出,栈溢出的出现场景以及解决方案
【7月更文挑战第3天】堆溢出(Heap Overflow)和栈溢出(Stack Overflow)是两种常见的内存溢出问题,通常发生在内存管理不当或设计不合理的情况下
12 3
|
15天前
|
监控 负载均衡 Java
Java虚拟机调优技巧及性能监控
Java虚拟机调优技巧及性能监控
|
1月前
|
运维 Java Shell
手工触发Full GC:JVM调优实战指南
本文是关于Java应用性能调优的指南,重点介绍了如何使用`jmap`工具手动触发Full GC。Full GC是对堆内存全面清理的过程,通常在资源紧张时进行以缓解内存压力。文章详细阐述了Full GC的概念,并提供了两种使用`jmap`触发Full GC的方法:通过`-histo:live`选项获取存活对象统计信息,或使用`-dump`选项生成堆转储文件以分析内存状态。同时,文中也提醒注意手动Full GC可能带来的性能开销,建议在生产环境中谨慎操作。
113 1
|
13天前
|
监控 负载均衡 Java
Java虚拟机调优技巧及性能监控
Java虚拟机调优技巧及性能监控
|
14天前
|
监控 Java 调度
探索JVM性能调优,调优不仅是技术挑战,更是成长过程。
【7月更文挑战第1天】探索JVM性能调优:** 本文深入JVM内存模型,关注堆内存与方法区、栈的优化,通过调整-Xms, -Xmx及垃圾收集器参数减少GC频率。探讨了Serial到G1等垃圾收集器的选择策略,利用jstat、jmap等工具诊断性能瓶颈。实战案例中,通过问题定位、内存分析解决Full GC问题,强调开发者需理解JVM原理,运用工具在复杂场景下实现高效调优。调优不仅是技术挑战,更是成长过程。
19 0