• Arthas 排查JVM问题总结


    一、安装

    Arthas官网:https://arthas.aliyun.com/中下载安装包。

    执行java -jar arthas-boot.jar就可以启动。

    image-20230908101838783

    二、常见命令

    • dashboard:查看JVM全局概览,包括线程、堆内存、GC还有系统信息等

    image-20230908004057353

    • thread:常见命令,查看线程。通过thread 查看线程详情信息。

    image-20230908004335178

    通过thread -b查看阻塞线程信息。

    image-20230908004426789

    • jad:反编译命令,能够将class文件反编译回源码。可以用在生产环境比较版本是否更新。

    image-20230908004631929

    • watch:查看方法参数

    • trace:查看方法内部调用路径,可以看到每条路径的耗时

    • stack:查看方法调用路径

    • redefine:将编译好的class热部署到环境

    • ognl:可以查看类中属性和方法执行情况。

    image-20230908005400528

    三、实践

    示例代码

    public class Arthas {
    
        private static HashSet hashSet = new HashSet();
    
        public String getName() {
            return "arthas";
        }
    
        public static void main(String[] args) {
            // 模拟 CPU 过高
            cpuHigh();
            // 模拟线程死锁
            deadThread();
            // 不断的向 hashSet 集合增加数据
            addHashSetThread();
        }
    
        /**
         * 不断的向 hashSet 集合添加数据
         */
        public static void addHashSetThread() {
            // 初始化常量
            new Thread(() -> {
                int count = 0;
                while (true) {
                    try {
                        hashSet.add("count" + count);
                        Thread.sleep(1000);
                        count++;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            },"my-arthas-thread").start();
        }
    
        public static void cpuHigh() {
            new Thread(() -> {
                while (true) {
    
                }
            },"my-arthas-thread1").start();
        }
    
        /**
         * 死锁
         */
        private static void deadThread() {
            /** 创建资源 */
            Object resourceA = new Object();
            Object resourceB = new Object();
            // 创建线程
            Thread threadA = new Thread(() -> {
                synchronized (resourceA) {
                    System.out.println(Thread.currentThread() + " get ResourceA");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread() + "waiting get resourceB");
                    synchronized (resourceB) {
                        System.out.println(Thread.currentThread() + " get resourceB");
                    }
                }
            },"my-arthas-thread2");
    
            Thread threadB = new Thread(() -> {
                synchronized (resourceB) {
                    System.out.println(Thread.currentThread() + " get ResourceB");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread() + "waiting get resourceA");
                    synchronized (resourceA) {
                        System.out.println(Thread.currentThread() + " get resourceA");
                    }
                }
            },"my-arthas-thread3");
            threadA.start();
            threadB.start();
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84

    查看死锁

    通过thread -b查看死锁情况:

    image-20230908104407779

    查看CPU飙升

    通过dashboard就能查看CPU占用情况:

    image-20230908104527155

    查看GC情况

    通过dashboard就能查看GC情况:

    image-20230908104659145

    查看接口调用太慢

    通过stack 来查看方法调用次数和时长。

    image-20230908105101387

    四、总结

    E4B52353-A4D1-413A-A98F-68658D32F749

    参考资料

    1. Arthas官网:https://arthas.aliyun.com/
    2. Arthas 使用详解:https://blog.csdn.net/zhangcongyi420/article/details/127252866
    3. 5-4-问题排查:https://www.pdai.tech/md/interview/x-interview.html#_5-4-问题排查

      本文由博客一文多发平台 OpenWrite 发布!

  • 相关阅读:
    【已解决】Git下载私有仓库时报错Authentication failed
    多线程
    C# CodeFormer 图像修复
    PMP_第8章章节试题
    实施方法论
    计算机网络高频面试题集锦
    Visual Studio Code 实用快捷键
    【教3妹学算法-每日一题】竞赛题:6160. 和有限的最长子序列
    服务于金融新核心系统 星辰天合与中电金信完成产品兼容认证
    VS Code如何使用服务器的Python开发环境
  • 原文地址:https://blog.csdn.net/ynkimage/article/details/132755878