前言
在使用Arthas排查线上问题的时候,有些时候我们需要查看某些类有没有被加载,或者这个类的静态成员变量到底有没有被打包,又或者需要load测试一下是否正常,那么这个时候可以通过本文进行相关的操作了。
Example
为了方便Arthas进行attach,我们手写一个死循环,如下
package cn.gov.zcy.itemplatform;
import java.util.concurrent.TimeUnit;
/**
* @author Duansg
* @date 2022-11-29 10:49 下午
*/
public class LoadClassExample {
public static void main(String[] args) throws InterruptedException {
while (true) {
TimeUnit.SECONDS.sleep(5);
}
}
}
然后定义一个不会被初始化加载的类
package cn.gov.zcy.itemplatform;
/**
* @author Duansg
* @date 2022-11-29 10:50 下午
*/
public class Duansg {
public static final String str = "helloworld";
}
Arthas Start
duansg@DuansiguodeMacBook-Pro ~ % java -jar ~/.arthas-boot.jar
[INFO] JAVA_HOME: /Library/Java/JavaVirtualMachines/zulu-11.jdk/Contents/Home
[INFO] arthas-boot version: 3.6.7
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 85856 cn.gov.zcy.itemplatform.LoadClassExample
1
[INFO] arthas home: /Users/duansg/.arthas/lib/3.6.7/arthas
[INFO] Try to attach process 85856
Picked up JAVA_TOOL_OPTIONS:
[WARN] Current VM java version: 11 do not match target VM java version: 1.8, attach may fail.
[WARN] It seems to use the higher version of JDK to attach the lower version of JDK.
[WARN] This error message can be ignored, the attach may have been successful, and it will still try to connect.
[INFO] Attach process 85856 success.
[INFO] arthas-client connect 127.0.0.1 3658
,---. ,------. ,--------.,--. ,--. ,---. ,---.
/ O \ | .--. ''--. .--'| '--' | / O \ ' .-'
| .-. || '--'.' | | | .--. || .-. |`. `-.
| | | || |\ \ | | | | | || | | |.-' |
`--' `--'`--' '--' `--' `--' `--'`--' `--'`-----'
wiki https://arthas.aliyun.com/doc
tutorials https://arthas.aliyun.com/doc/arthas-tutorials.html
version 3.6.7
main_class cn.gov.zcy.itemplatform.LoadClassExample
pid 85856
time 2022-11-29 23:04:57
[arthas@85856]$
Arthas-idea-plugin
Classloader Load Class
我们直接在这个未初始化加载的类上选择如下
Search Class In Jvm
会弹出如下对话框,选择copy
然后再Arthas控制台粘贴复制好的命令,如下
// 执行命令以后是没有任何信息输出的
[arthas@85856]$ sc -d cn.gov.zcy.itemplatform.Duansg
Affect(row-cnt:0) cost in 13 ms.
Classloader List
查找当前Jvm的Clasloader的列表
然后再Arthas控制台粘贴复制好的命令,如下
[arthas@85856]$ classloader -l
name loadedCount hash parent
BootstrapClassLoader 2511 null null
com.taobao.arthas.agent.ArthasClassloader@734ba29e 1360 734ba29e sun.misc.Launcher$ExtClassLoader@55512d1a
sun.misc.Launcher$AppClassLoader@18b4aac2 159 18b4aac2 sun.misc.Launcher$ExtClassLoader@55512d1a
sun.misc.Launcher$ExtClassLoader@55512d1a 63 55512d1a null
Affect(row-cnt:4) cost in 13 ms.
Load Class
我们使用上文中的AppClassLoader@18b4aac2,将hash值填入,然后复制load class命令
然后再Arthas控制台粘贴复制好的命令,如下
[arthas@85856]$ classloader --load cn.gov.zcy.itemplatform.Duansg -c 18b4aac2
load class success.
class-info cn.gov.zcy.itemplatform.Duansg
code-source /Users/duansg/app/workspace/item-platform/item-test/target/test-classes/
name cn.gov.zcy.itemplatform.Duansg
isInterface false
isAnnotation false
isEnum false
isAnonymousClass false
isArray false
isLocalClass false
isMemberClass false
isPrimitive false
isSynthetic false
simple-name Duansg
modifier public
annotation
interfaces
super-class +-java.lang.Object
class-loader +-sun.misc.Launcher$AppClassLoader@18b4aac2
+-sun.misc.Launcher$ExtClassLoader@55512d1a
classLoaderHash 18b4aac2
可以看到是加载成功了,为了验证是否加载成功,我们在执行一次Search Class In Jvm,如下
[arthas@85856]$ sc -d cn.gov.zcy.itemplatform.Duansg
class-info cn.gov.zcy.itemplatform.Duansg
code-source /Users/duansg/app/workspace/item-platform/item-test/target/test-classes/
name cn.gov.zcy.itemplatform.Duansg
isInterface false
isAnnotation false
isEnum false
isAnonymousClass false
isArray false
isLocalClass false
isMemberClass false
isPrimitive false
isSynthetic false
simple-name Duansg
modifier public
annotation
interfaces
super-class +-java.lang.Object
class-loader +-sun.misc.Launcher$AppClassLoader@18b4aac2
+-sun.misc.Launcher$ExtClassLoader@55512d1a
classLoaderHash 18b4aac2
Affect(row-cnt:1) cost in 17 ms.
Simple Ger Static Field
加载成功以后,我们可以验证一下获取此类的静态变量,如下
可以看到,我们定义的静态成员变量是正常输出的。
[arthas@85856]$ getstatic cn.gov.zcy.itemplatform.Duansg str -x 3
field: str
@String[helloworld]
Affect(row-cnt:1) cost in 11 ms.
小结
至此,整个加载跟验证过程都是ok的,你可以通过此类方式进行推导你遇到的问题,当然这里面很多的功能还需要在继续探索。