@toc
提示:
“Search-Method” 的简写,这个命令能搜索出所有已经加载了 Class 信息的方法信息。
sm
命令只能看到由当前类所声明 (declaring) 的方法,父类则无法看到。
参数说明:
参数名称 | 参数说明 |
---|---|
class-pattern | 类名表达式匹配 |
method-pattern | 方法名表达式匹配 |
d | 展示每个方法的详细信息 |
E | 开启正则表达式匹配,默认为通配符匹配 |
| 指定 class 的 ClassLoader 的 hashcode |
| 指定执行表达式的 ClassLoader 的 class name |
| 具有详细信息的匹配类的最大数量(默认为 100 |
问题:这sm方法有啥用?我只能看出方法入参类型 返回类型等等,你又看不到具体的代码逻辑 感觉没用啊
答案:用途和好处
sm
命令帮助你快速了解某个方法的签名信息。这包括方法的返回类型、参数类型以及访问修饰符(如 public
, private
, static
等)。这对于你在调试时确认方法调用的正确性非常重要。sm -d
命令,可以获取更详细的方法元数据,包括方法的声明类、修饰符、注解、异常等。这有助于了解方法的具体定义和它的上下文。sm
命令不显示具体的代码逻辑,但了解方法的签名可以帮助你在其他调试任务中更好地理解方法的作用和调用。例如,在使用 monitor
或 trace
等命令时,你可以基于方法的签名来确认你正在监控或追踪正确的方法。sm
命令验证一个类中是否存在某个方法,以及它的参数和返回类型是否符合你的预期。这在检查类的正确性或调试异常时非常有用。代码:
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();
}
}
}
基础语法
: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]$
基础语法
: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]$
2.Arthas dashboard(当前系统的实时数据面板)
3.Arthas thread(查看当前JVM的线程堆栈信息)
5.Arthas sysprop(查看和修改JVM的系统属性)
7.Arthas vmoption(查看和修改 JVM里诊断相关的option)
9.Arthas heapdump(dump java heap, 类似 jmap 命令的 heap dump 功能)
10.Arthas logger(查看 logger 信息,更新 logger level)
14.Arthas perfcounter(查看当前 JVM 的 Perf Counter 信息)
15.Arthas vmtool(从 jvm 里查询对象,执行 forceGc)
17.Arthas mc(Memory Compiler/内存编译器 )
18.Arthas redefine(加载外部的.class文件,redefine到JVM里 )
19.Arthas classloader (查看 classloader 的继承树,urls,类加载信息)
23.Arthas stack (输出当前方法被调用的调用路径)
24.Arthas trace (方法内部调用路径,并输出方法路径上的每个节点上耗时)
25.Arthas tt(方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测)
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有