Arthas sm(查看已加载类的方法信息 )

在这里插入图片描述

二、命令列表

2.2 class/classloader相关命令

2.2.6 sm(查看已加载类的方法信息 )

提示:

“Search-Method” 的简写,这个命令能搜索出所有已经加载了 Class 信息的方法信息。

sm 命令只能看到由当前类所声明 (declaring) 的方法,父类则无法看到。

参数说明:

参数名称参数说明
class-pattern类名表达式匹配
method-pattern方法名表达式匹配
[d]展示每个方法的详细信息
[E]开启正则表达式匹配,默认为通配符匹配
[c:]指定 class 的 ClassLoader 的 hashcode
[classLoaderClass:]指定执行表达式的 ClassLoader 的 class name
[n:]具有详细信息的匹配类的最大数量(默认为 100

问题:这sm方法有啥用?我只能看出方法入参类型 返回类型等等,你又看不到具体的代码逻辑 感觉没用啊

答案:用途和好处

  1. 了解方法签名sm 命令帮助你快速了解某个方法的签名信息。这包括方法的返回类型、参数类型以及访问修饰符(如 public, private, static 等)。这对于你在调试时确认方法调用的正确性非常重要。
  2. 方法元数据:通过 sm -d 命令,可以获取更详细的方法元数据,包括方法的声明类、修饰符、注解、异常等。这有助于了解方法的具体定义和它的上下文。
  3. 分析方法的调用:虽然 sm 命令不显示具体的代码逻辑,但了解方法的签名可以帮助你在其他调试任务中更好地理解方法的作用和调用。例如,在使用 monitortrace 等命令时,你可以基于方法的签名来确认你正在监控或追踪正确的方法。
  4. 验证方法的存在:你可以使用 sm 命令验证一个类中是否存在某个方法,以及它的参数和返回类型是否符合你的预期。这在检查类的正确性或调试异常时非常有用。
  5. 调试和分析:在进行性能调优或分析时,了解方法的签名有助于你识别方法调用的瓶颈,或者确认方法是否按预期工作。

代码:

public class SMTaskCache
{
    private static SMTaskCache instance = new SMTaskCache();

    // 缓存
    public static final Vector<SmconfigDmTaskMain> taskCache = new Vector<>();

    // 读写锁
    private final static ReadWriteLock lock = new ReentrantReadWriteLock();

    public static SMTaskCache getInstance()
    {
        return instance;
    }

    private SMTaskCache()
    {

    }

    /**
     * 向缓存中添加对象
     * @param info
     */
    public static void add(SmconfigDmTaskMain info)
    {
        try
        {
            lock.writeLock().lock();
            for (SmconfigDmTaskMain smconfigdmtaskmain : taskCache)
            {
                if (smconfigdmtaskmain.getSysTaskId().equals(info.getSysTaskId()))
                {
                    taskCache.remove(smconfigdmtaskmain);
                    break;
                }
            }
            taskCache.add(info);
        }
        finally
        {
            lock.writeLock().unlock();
        }
    }

    /**
     * 向缓存中添加对象
     * @param infos
     */
    @Autowired
    public static void add(List<SmconfigDmTaskMain> infos)
    {
        try
        {
            lock.writeLock().lock();
            for (SmconfigDmTaskMain info : infos)
            {
                add(info);
            }
        }
        finally
        {
            lock.writeLock().unlock();
        }
    }

    /**
     * 从缓存中删除对象
     * @param sysTaskId
     */
    public static void remove(Long sysTaskId)
    {
        try
        {
            lock.writeLock().lock();
            if (taskCache.size() > 0)
            {
                for (SmconfigDmTaskMain smconfigdmtaskmain : taskCache)
                {
                    if (smconfigdmtaskmain.getSysTaskId().equals(sysTaskId))
                    {
                        taskCache.remove(smconfigdmtaskmain);
                        return;
                    }
                }
            }
        }
        finally
        {
            lock.writeLock().unlock();
        }
    }

    /**
     * 获取task状态
     * @param smconfigdmtaskmain
     * @return
     */
    public static SmconfigDmTaskMain getTaskStatus(SmconfigDmTaskMain smconfigdmtaskmain)
    {
        try
        {
            lock.readLock().lock();
            for (SmconfigDmTaskMain taski : taskCache)
            {
                if (taski.getSysTaskId().equals(smconfigdmtaskmain.getSysTaskId()))
                {
                    smconfigdmtaskmain.setSysTaskState(taski.getSysTaskState());
                    smconfigdmtaskmain.setSysTaskNextTime(taski.getSysTaskNextTime());
                    smconfigdmtaskmain.setTaskSwitch(taski.getTaskSwitch());
                }
            }
            return smconfigdmtaskmain;
        }
        finally
        {
            lock.readLock().unlock();
        }
    }

    /**
     * 获取task状态
     * @param smconfigdmtaskmains
     * @return
     */
    public static List<SmconfigDmTaskMain> getTaskStatus(List<SmconfigDmTaskMain> smconfigdmtaskmains)
    {
        try
        {
            lock.readLock().lock();
            for (SmconfigDmTaskMain smconfigdmtaskmain : smconfigdmtaskmains)
            {
                getTaskStatus(smconfigdmtaskmain);
            }
            return smconfigdmtaskmains;
        }
        finally
        {
            lock.readLock().unlock();
        }
    }

    /**
     * 初始化task状态
     * @param sysTaskId
     * @param nextTime
     */
    public static void initTask(Long sysTaskId, Date nextTime, Integer taskSwitch)
    {
        try
        {
            lock.writeLock().lock();
            Long curTime = System.currentTimeMillis();
            for (SmconfigDmTaskMain smconfigdmtaskmain : taskCache)
            {
                if (smconfigdmtaskmain.getSysTaskId().equals(sysTaskId))
                {//如果当前任务有结束时间,需要判断任务是否已经过期
                    if(smconfigdmtaskmain.getSysTaskEndTime() != null && smconfigdmtaskmain.getSysTaskEndTime().getTime() <= curTime){
                        smconfigdmtaskmain.setSysTaskState(SMTaskStatusEnum.PASTDUE.getCodeString());
                        smconfigdmtaskmain.setTaskSwitch(SMTaskSwitchEnum.INVALID.getCode());
                    }else if(SMTaskSwitchEnum.INVALID.getCode().equals(taskSwitch)){
                        smconfigdmtaskmain.setSysTaskState(SMTaskStatusEnum.PAUSE.getCodeString());
                        smconfigdmtaskmain.setTaskSwitch(SMTaskSwitchEnum.INVALID.getCode());
                    }else{
                        smconfigdmtaskmain.setSysTaskState(SMTaskStatusEnum.READY.getCodeString());
                        smconfigdmtaskmain.setTaskSwitch(SMTaskSwitchEnum.ACTIVE.getCode());
                    }
                    smconfigdmtaskmain.setSysTaskNextTime(nextTime);
                }
            }
        }
        finally
        {
            lock.writeLock().unlock();
        }
    }
    /**
     * 更新task状态为暂停
     * @param sysTaskId
     */
    public static void pasueTask(Long sysTaskId)
    {
        try
        {
            lock.writeLock().lock();
            Long curTime = System.currentTimeMillis();
            for (SmconfigDmTaskMain smconfigdmtaskmain : taskCache)
            {
                if (smconfigdmtaskmain.getSysTaskId().equals(sysTaskId))
                {//如果当前任务有结束时间,需要判断任务是否已经过期
                    if(smconfigdmtaskmain.getSysTaskEndTime() != null && smconfigdmtaskmain.getSysTaskEndTime().getTime() <= curTime){
                        smconfigdmtaskmain.setSysTaskState(SMTaskStatusEnum.PASTDUE.getCodeString());
                        smconfigdmtaskmain.setTaskSwitch(SMTaskSwitchEnum.INVALID.getCode());
                    }else {
                        smconfigdmtaskmain.setSysTaskState(SMTaskStatusEnum.PAUSE.getCodeString());
                        smconfigdmtaskmain.setTaskSwitch(SMTaskSwitchEnum.INVALID.getCode());
                    }
                }
            }
        }
        finally
        {
            lock.writeLock().unlock();
        }
    }

    /**
     * 开始任务
     * @param sysTaskId
     * @param nextTime
     */
    public static void executeTask(Long sysTaskId, Date nextTime)
    {
        try
        {
            lock.writeLock().lock();
            Long curTime = System.currentTimeMillis();
            for (SmconfigDmTaskMain smconfigdmtaskmain : taskCache)
            {
                if (smconfigdmtaskmain.getSysTaskId().equals(sysTaskId))
                {
                    //如果当前任务有结束时间,需要判断任务是否已经过期
                    if(smconfigdmtaskmain.getSysTaskEndTime() != null && smconfigdmtaskmain.getSysTaskEndTime().getTime() <= curTime){
                        smconfigdmtaskmain.setSysTaskState(SMTaskStatusEnum.PASTDUE.getCodeString());
                        smconfigdmtaskmain.setTaskSwitch(SMTaskSwitchEnum.INVALID.getCode());
                    }else{
                        smconfigdmtaskmain.setSysTaskState(SMTaskStatusEnum.EXECUTING.getCodeString());
                        smconfigdmtaskmain.setTaskSwitch(SMTaskSwitchEnum.ACTIVE.getCode());
                    }
                    smconfigdmtaskmain.setSysTaskNextTime(nextTime);
                }
            }
        }
        finally
        {
            lock.writeLock().unlock();
        }
    }

    /**
     * 结束任务
     * @param sysTaskId 任务ID
     * @param externalCallFlag 【true:为外部接口curl命令调用;false:系统任务内部调用】
     */
    public static void executeTaskEnd(Long sysTaskId, boolean externalCallFlag)
    {
        //如果externalCallFlag为true,则不修改系统任务的状态,直接跳过
        if (externalCallFlag) {
            return;
        }
        try
        {
            lock.writeLock().lock();
            Long curTime = System.currentTimeMillis();
            for (SmconfigDmTaskMain smconfigdmtaskmain : taskCache)
            {
                if (smconfigdmtaskmain.getSysTaskId().equals(sysTaskId))
                {
                    //如果当前任务有结束时间,需要判断任务是否已经过期
                    if(smconfigdmtaskmain.getSysTaskEndTime() != null && smconfigdmtaskmain.getSysTaskEndTime().getTime() <= curTime){
                        smconfigdmtaskmain.setSysTaskState(SMTaskStatusEnum.PASTDUE.getCodeString());
                        smconfigdmtaskmain.setTaskSwitch(SMTaskSwitchEnum.INVALID.getCode());
                    }else{
                        smconfigdmtaskmain.setTaskSwitch(SMTaskSwitchEnum.ACTIVE.getCode());
                        smconfigdmtaskmain.setSysTaskState(SMTaskStatusEnum.READY.getCodeString());
                    }
                }
            }
        }
        finally
        {
            lock.writeLock().unlock();
        }
    }
}
举例1:显示类加载的方法

基础语法

sm 全路径类名

[arthas@18139]$ sm com.hero.lte.ems.sysmanager.cache.SMTaskCache
com.hero.lte.ems.sysmanager.cache.SMTaskCache <init>()V
com.hero.lte.ems.sysmanager.cache.SMTaskCache executeTask(Ljava/lang/Long;Ljava/util/Date;)V
com.hero.lte.ems.sysmanager.cache.SMTaskCache getTaskStatus(Lcom/hero/lte/ems/sysmanager/model/SmconfigDmTaskMain;)Lcom/hero/lte/ems/sysmanager/model/SmconfigDmTaskMain;
com.hero.lte.ems.sysmanager.cache.SMTaskCache getTaskStatus(Ljava/util/List;)Ljava/util/List;
com.hero.lte.ems.sysmanager.cache.SMTaskCache initTask(Ljava/lang/Long;Ljava/util/Date;Ljava/lang/Integer;)V
com.hero.lte.ems.sysmanager.cache.SMTaskCache pasueTask(Ljava/lang/Long;)V
com.hero.lte.ems.sysmanager.cache.SMTaskCache executeTaskEnd(Ljava/lang/Long;Z)V
com.hero.lte.ems.sysmanager.cache.SMTaskCache add(Lcom/hero/lte/ems/sysmanager/model/SmconfigDmTaskMain;)V
com.hero.lte.ems.sysmanager.cache.SMTaskCache add(Ljava/util/List;)V
com.hero.lte.ems.sysmanager.cache.SMTaskCache remove(Ljava/lang/Long;)V
com.hero.lte.ems.sysmanager.cache.SMTaskCache getInstance()Lcom/hero/lte/ems/sysmanager/cache/SMTaskCache;
Affect(row-cnt:11) cost in 18 ms.
[arthas@18139]$
举例2:显示类加载的executeTask方法详细信息

基础语法

sm -d 全路径类名 方法名

[arthas@18139]$ sm -d com.hero.lte.ems.sysmanager.cache.SMTaskCache executeTask
 declaring-class  com.hero.lte.ems.sysmanager.cache.SMTaskCache                                                                                                                                                                         
 method-name      executeTask                                                                                                                                                                                                           
 modifier         public,static                                                                                                                                                                                                         
 annotation                                                                                                                                                                                                                             
 parameters       java.lang.Long                                                                                                                                                                                                        
                  java.util.Date                                                                                                                                                                                                        
 return           void                                                                                                                                                                                                                  
 exceptions                                                                                                                                                                                                                             
 classLoaderHash  18b4aac2                                                                                                                                                                                                              

Affect(row-cnt:1) cost in 15 ms.
[arthas@18139]$ 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘大猫.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值