阅读 76

JVM程序CPU爆表问题排查 - 线程篇

[TOC]


使用 JVM Jsatck 命令定位使服务器 CPU 爆炸的类 & 方法。

CentOS 7 服务下

首先给出一段示例代码:
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Hello world!
 */
public class App {

    private static final AtomicInteger atomic = new AtomicInteger(0);

    private static final Integer randomInteger = new Random().nextInt(100);

    private static final Object LOCK = new Object();

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            synchronized (LOCK) {
                threadFunc();
                atomic.addAndGet(1);
            }
        }
    }

    public static void threadFunc() {
        new Thread(() -> {
            if (randomInteger.equals(atomic.get())) {
                // 这里会让服务器出现 CPU 100% 占用
                while (!UUID.randomUUID().toString().equals("HELLO,WORLD!")) {
                }
            }
        }).start();
    }
}
使用 top 命令查看服务器资源占用情况
截屏2021-01-17 下午7.04.36.png

可以很明显的看到 PID 为 14168 的 java 程序出现了 CPU 99.9 % 的占用

使用 Jvm jps 命令确认占用CPU过高的程序
image.png

可以看到 14168 是名称为 APP 的程序。

使用 Jvm jstack 命令打印出 dump 堆栈信息

jstack [pid] > ps.log

image.png
进入 top 使用 shift + h 查看占用 CPU 较高的线程号
image.png

可以看到占用 CPU 较高的线程号是 14226

使用打印出的 dump 信息查看线程信息。

首先将 14226 转换为 16 进制。printf '%x\n' 14226 输出 3792

使用 grep -A 20 3792 ps.log 查看线程信息

image.png

可以看到是 App.java 文件 中的 threadFunc 方法。

总结
  1. Top 命令查看CPU过高的应用
  2. 使用 Jps 命令定位程序
  3. 使用 jstack [pid] > [文件] 打印出 dump 文件
  4. 进入 top 使用 shift + h 切换查看线程信息
  5. 使用 printf '%x\n' [tid] 将线程ID转换为 16 进制
  6. 进入 dump 文件通过转换过后的 16 进制线程号。搜索线程信息。定位类和方法。
  7. 人工分析代码BUG

github
个人博客
扩展内容

作者:YUNDONG丶

原文链接:https://www.jianshu.com/p/59d04cdbb6bb

文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐