0、编译
jad com.cc.ctrl.className
1、热替换代码
1.修改代码并copy到指定目录,如D:\arttest\demo\MathGame.java
2.进入arthas执行编译命令
mc D:/arttest/demo/MathGame.java -d D:/arttest/
3.执行替换命令
retransform D:/arttest/demo/MathGame.class
4.查看
retransform -l
以数值最大的为生效
2、恢复热替换代码
1、需要删除所有的替换entry
retransform --deleteAll
retransform -d 1
2、重新触发
retransform --classPattern demo.MathGame
3、SpringBoot集成
引入依赖
<dependency>
<groupId>com.taobao.arthas</groupId>
<artifactId>arthas-spring-boot-starter</artifactId>
<version>3.5.5</version>
</dependency>
启动服务并连接
telnet localhost 3658
4、观察方法执行watch
watch com.example.ctrl.ExampleCtrl methodName
- params:参数
- returnObj:返回值
- throwExp:抛出的异常
- target:代表this,指当前对象
- clazz:当前类
- {xxxx,xxxx} :ognl表达式
5、查看方法调用栈stack
stack com.example.dao.HostPhysicalGpuDAO save -n 1
6、查看方法调用链耗时trace
trace --skipJDKMethod false com.example.dao.HostPhysicalGpuDAO save '#cost>10' -n 1
- --skipJDKMethod false:不跳过jdk调用链
- cost:耗时>10ms
7、时空隧道tt
@RestController
public class ExampleCtrl {
@Autowired
private HostPhysicalGpuDAO hostPhysicalGpuDAO;
private static final Integer AA = 1;
private static String test() {
return "ok";
}
@GetMapping(value="/cc")
public String example() {
return "ok";
}
@GetMapping(value="/dd")
public String dd() {
HostPhysicalGpuEntity entity = new HostPhysicalGpuEntity();
entity.setId(UUID.randomUUID());
entity.setVendor("AA");
entity.setSlot(1);
entity.setHostId(UUID.randomUUID());
entity.setName("AMD");
hostPhysicalGpuDAO.save(entity);
return "okk";
}
@GetMapping(value="/aa")
public List<HostPhysicalGpuEntity> aa() {
List<HostPhysicalGpuEntity> list = hostPhysicalGpuDAO.findAllByHostId(UUID.fromString("9930005b-0d84-46b0-8cb1-54eb50ff58dc"));
return list;
}
@GetMapping(value="/ee")
public String ee(String a) {
return a;
}
}
录制
tt -t com.example.ctrl.ExampleCtrl ee
查询
tt -l
回放
tt -i 1000
调用静态方法
tt -w 'target.test()' -i 1000
执行类方法
tt -w 'target.ee("s")' -i 1000
ognl执行静态方法
tt -w '@com.example.ctrl.ExampleCtrl@test()' -i 1000
获取bean
tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod
tt -i 1000 -w 'target.getApplicationContext().getBean("exampleCtrl").example()'
传参数,静态构造
tt -i 1000 -w '#data=@java.util.UUID@fromString("81724d71-33eb-512b-a2a5-07f2fe61bb13"),target.getApplicationContext().getBean("xxx").remove(#data)'
传参数,new构造
tt -i 1000 -w '#data=new com.example.entity.HostPhysicalGpuEntity(),#ids=@java.util.UUID@fromString("81724d71-33eb-512b-a2a5-07f2fe61bb13"),#data.setId(#ids),target.getApplicationContext().getBean("exampleCtrl").ff(#data)'
8、线程
找出当前阻塞其他线程的线程(只支持找出synchronized关键字)
thread -b
查找指定状态
thread --state BLOCKED
查看最忙得3个线程
thread -n 3
9、JVM属性&系统环境变量
列出JVM所有属性
sysprop
获取JVM单个属性
sysprop key
修改JVM单个属性
sysprop key value
列出系统环境变量
sysenv
获取单个环境变量
sysenv key
10. 获取内存中的对象
vmtool --action getInstances --className com.example.ctrl.ExampleCtrl --limit 10 -x 2
11.获取类中的静态变量
getstatic com.example.ctrl.ExampleCtrl MAP -x 2