文章目录
- 二、命令列表
- 2.2 class/classloader相关命令
- 2.2.6 sm(查看已加载类的方法信息 )
- 举例1:显示类加载的方法
- 举例2:显示类加载的executeTask方法详细信息
二、命令列表
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方法有啥用?我只能看出方法入参类型 返回类型等等,你又看不到具体的代码逻辑 感觉没用啊
答案:用途和好处
- 了解方法签名:
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();
}
}
}
举例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]$