retransform
加载外部的.class文件,retransform jvm已加载的类
命令选项
命令选项 | 描述 |
---|---|
-c, --classloader <hash> | 指定ClassLoader的哈希值 |
--classLoaderClass <class-name> | 指定ClassLoader的类名 |
--classPattern <pattern> | 通过模式匹配类触发retransform |
-d, --delete <id> | 删除给定id的retransform entry |
--deleteAll | 删除所有retransform entry |
--limit <number> | 限制dump class的数量,默认50 |
-l, --list | 列出所有retransform entry |
-h, --help | 帮助 |
<classFilePaths> | class文件路径 |
示例
修改MathGame代码如下
java
public void run() throws InterruptedException {
System.out.println("I'm running again!");
try {
int number = random.nextInt()/10000;
List<Integer> primeFactors = primeFactors(number);
print(number, primeFactors);
} catch (Exception e) {
System.out.println(String.format("illegalArgumentCount:%3d, ", illegalArgumentCount) + e.getMessage());
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
bash
# 编译修改后的java文件
[arthas@13728]$ mc -d /tmp /tmp/MathGame.java
Memory compiler output:
C:\tmp\demo\MathGame.class
Affect(row-cnt:1) cost in 50 ms.
# retransform MathGame
[arthas@13728]$ retransform /tmp/demo/MathGame.class
redefine success, size: 1, classes:
demo.MathGame
# retransform后控制台输出如下
I'm running again!
illegalArgumentCount:4779, number is: -16285, need >= 2
I'm running again!
illegalArgumentCount:4780, number is: -164989, need >= 2
I'm running again!
illegalArgumentCount:4781, number is: -36742, need >= 2
# 列出当前retransform entry列表
[arthas@13728]$ retransform -l
Id ClassName TransformCount LoaderHash LoaderClassName
59 demo.MathGame 1 null null
# 还原retransform类
retransform --deleteAll
reset
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
注意
- 不允许新增加 field/method
- 正在运行的函数,没有结束不能生效
- 如果多次执行 retransform 加载同一个 class 文件,则会有多条 retransform entry
- 对于同一个类,当存在多个 retransform entry 时,如果显式触发 retransform ,则最后添加的 entry 生效(id 最大的)
- 如果不清除掉所有的 retransform entry,并重新触发 retransform ,则 arthas stop 时,retransform 过的类仍然生效。
- 删除所有retransform entry,可用reset命令还原