前言
jvm分析工具有很多,但是我还是用jmap jstack 和arthas。
阿里的东西确实不错~
要整的东西有好多,接下来看G1的回收算法。
arthas怎么读?[ 'ɑ: θs ] 阿瑟斯
使用
https://arthas.aliyun.com/doc/quick-start.html
可以用这个快速入门;
下载:
curl -O https://arthas.aliyun.com/arthas-boot.jar
启动arthas
java -jar arthas-boot.jar
dashboard
当前系统的实时数据面板:包括线程、JVM、操作系统属性等
(信息可以看到JVM的内存信息,也可以查看到每个区域的GC信息。同时也可以看到使用的垃圾收集器是JDK8默认的-XX:+UseParallelGC 使用ParallelScavenge + Serial Old(PS MarkSweep)收集器组合)
可以看到线程,JVM内存信息,虚拟机和操作系统的基本信息,做日常监控很不错。
退出
如果只是退出当前的连接,可以用quit或者exit命令。Attach到目标进程上的arthas还会继续运行,端口会保持开放,下次连接时可以直接连接上。
如果想完全退出arthas,可以执行exit/stop命令。
sysenv 查看JVM的环境变量
sysprop 查看JVM的所有的系统属性
sysprop java.version 查看单个系统的属性
sysprop user.country US 修改user.country 属性的值为US
比如上面修改 test 属性为 testValue,修改之后会被程序System.getProperty(key) 获取到
Sc:
sc [-d] className
-d 通过-d参数,可以打印出类加载的具体信息,很方便查找类加载问题。
sc支持通配,比如搜索所有的StringUtils:sc *StringUtils
watch:
输入 Q 或者 Ctrl+C 退出watch命令。
watch 全类名 方法名
watch com.test.ob testMethod “{params, returnObj, throwExp}” -e -x 2
getstatic
getstatic class_name field_name
-c 指定类加载器hash,可以通过sc 全类名获取类加载器hash
–classLoaderClass 指定类加载器的名字
比如:
只观测方法进入时的入参,无返回值时,可以这样写
watch 类名表达式 方法名表达式 "{params}" -b -x 2
只观察方法异常时的出餐和返回值时,可以这样写
watch 类名表达式 方法名表达式 "{params,returnObj}" -e -x 2
只观察方法的正常返回时的出参和返回值时,可以这样写
watch 类名表达式 方法名表达式 "{params,returnObj}" -s -x 2
我遇到过的线上问题
因为hive执行很长,但是没有报错,比如任务米有提交上去,一直在跑。
在做数据同步一期的时候,会有这样的任务一直卡着。
所以需要基线监控。
在生产或者测试环境有些方法执行比较耗时,一种简单粗暴的方法是在可能的地点打日志进行监视,另一种就是借助于插件进行检测。而且也可以用于查看JVM信息、线程信息以及系统属性等信息。
然后会选择已经存在的java process
选择我们的服务
arthas 会自动检测进程ID,需要自己选择一个PID然后进入
命令:options
options save-result true 开启保存日志。会保存到{user}/logsarthas-cache/result.log 中
也是通过阿瑟斯来进行一些线程问题的分析,分析线程卡死等原因。
网上的一些arthas案例
统计解码方法中耗时大于1ms的方法调用
[arthas@24222]$ trace *.ProtocolService decode '#cost > 1'
stack-统计当前方法的调用路径(了解当前方法都被哪些方法调用过)
其实统计的就是堆栈信息,和报异常打印的堆栈信息类似。
代码实战
统计decode方法的调用堆栈,只显示两条数据
[arthas@24222]$ stack *.ProtocolService decode -n 2
tt-记录下每次方法调用的环境现场
tt存在的意义在于可以完整的记录针对当前方法的所有调用信息,包括每次调用的出入参(准确来说是出参,如果方法中对入参没有任何修改,那么出参=入参)返回值等等。
代码实战:
记录下decode方法的最近4次的方法调用,然后查看其中某一次方法调用。
[arthas@24222]$ tt -t *.ProtocolService decode -n 4
monitor-方法执行统计(非实时方法)
monitor命令会给出一个周期内的某方法的统计信息,包括,调用次数成功次数失败次数,平均调用时间失败率等等。
代码实战:
每10秒统计一次,decode方法相关信息
[arthas@24222]$ monitor -c 10 *.ProtocolService decode
总结
重要:
sc命令可以查看jvm已经加载的类信息。
watch主要用于观察 方法 的入参 出参 返回值 和 异常等信息
想查看一个配置类是否被正确加载进来,就可以使用sc命令实现
不太重要的:
sm可以查看加载到元数据区的方法
jad可以线上反编译class字节码
trace匹配的是对应方法字节码中的方法调用指令(invokeXXX指令,只能从当前方法开始匹配第一层子方法,无法继续深入,如果想要监控方法调用链上的多层,需要用正则表达式手动匹配多个类和方法)