Arthas - Java诊断利器

项目标题与描述

Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱。它允许开发者在生产环境中对Java应用进行问题诊断,而无需修改代码或重启服务器。Arthas支持JDK 6+,兼容Linux/Mac/Windows平台,采用命令行交互模式,提供丰富的Tab自动补全功能,极大提升了问题定位和诊断的效率。

功能特性

  • 类加载查看:查看类从哪个jar包加载,解决类冲突问题
  • 方法监控:监控方法调用参数、返回值和异常
  • 性能分析:生成火焰图,快速定位热点方法
  • 动态追踪:无需重启即可追踪方法调用链路
  • 在线诊断:直接在生产环境调试,无需线下重现
  • JVM监控:实时查看JVM运行状态和系统属性
  • 字节码增强:动态修改类字节码进行问题修复
  • 多会话支持:支持多人同时诊断同一应用

安装指南

快速安装

使用以下命令一键安装Arthas:

curl -L https://arthas.aliyun.com/install.sh | sh

手动安装

  1. 下载最新版Arthas:
curl -O https://arthas.aliyun.com/arthas-boot.jar
  1. 启动Arthas:
java -jar arthas-boot.jar

系统要求

  • JDK 6或更高版本
  • Linux/Mac/Windows操作系统
  • 至少100MB磁盘空间

使用说明

基础使用

  1. 启动Arthas并附加到目标Java进程:
java -jar arthas-boot.jar
  1. 查看帮助信息:
help
  1. 监控方法执行:
watch com.example.Class method "{params,returnObj}" -x 2

常用命令示例

  • 查看JVM信息:
jvm
  • 反编译类:
jad java.lang.String
  • 监控方法调用:
trace com.example.Service * '#cost>100'
  • 生成火焰图:
profiler start
profiler stop

核心代码

类加载器实现

public class ArthasClassloader extends URLClassLoader {
    public ArthasClassloader(URL[] urls) {
        super(urls, ClassLoader.getSystemClassLoader().getParent());
    }

    @Override
    protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        final Class<?> loadedClass = findLoadedClass(name);
        if (loadedClass != null) {
            return loadedClass;
        }

        // 优先从parent(SystemClassLoader)里加载系统类
        if (name != null && (name.startsWith("sun.") || name.startsWith("java.")) {
            return super.loadClass(name, resolve);
        }
        try {
            Class<?> aClass = findClass(name);
            if (resolve) {
                resolveClass(aClass);
            }
            return aClass;
        } catch (Exception e) {
            // ignore
        }
        return super.loadClass(name, resolve);
    }
}

方法监控实现

public abstract class AbstractTraceAdviceListener extends AdviceListenerAdapter {
    protected final ThreadLocalWatch threadLocalWatch = new ThreadLocalWatch();
    
    @Override
    public void before(ClassLoader loader, Class<?> clazz, ArthasMethod method, Object target, Object[] args) {
        threadLocalWatch.start();
    }
    
    @Override
    public void afterReturning(ClassLoader loader, Class<?> clazz, ArthasMethod method, Object target, Object[] args,
                             Object returnObject) {
        double cost = threadLocalWatch.costInMillis();
        // 处理监控结果
    }
}

JVM信息获取

public class JvmCommand extends AnnotatedCommand {
    private final RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
    private final ClassLoadingMXBean classLoadingMXBean = ManagementFactory.getClassLoadingMXBean();
    
    private void addRuntimeInfo(JvmModel jvmModel) {
        Map<String, String> runtimeInfo = new LinkedHashMap<String, String>();
        runtimeInfo.put("MACHINE-NAME", runtimeMXBean.getName());
        runtimeInfo.put("JVM-START-TIME", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                        .format(new Date(runtimeMXBean.getStartTime())));
        jvmModel.setRuntimeInfo(runtimeInfo);
    }
}

更多精彩内容 请关注我的个人公众号 公众号(办公AI智能小助手)
公众号二维码

posted @ 2025-07-30 23:01  qife  阅读(3)  评论(0)    收藏  举报