前言:此文仅为笔者学习Arthas源码的一次尝试,不对本文结论负全部责任。
一、背景
笔者在学习arthas这个十分方便的小工具的过程中,发现:
目前据arthas官方解释:因为trace多层是十分消耗资源的,因此trace命令只会支持一层的耗时分析。
如果出现如下图的情况,trace命令的处理就会变得十分麻烦。
因此,是否可以考虑在arthas中增加一个命令或者给trace命令增加一个参数,来使其支持分析多层结果?
那么理应设立一种规则,如:
- 展开最大耗时方法的明细
- 展开大于多少耗时的方法明细
- 展开耗时前n个方法的明细
本文假定将规则定为展开耗时前n个方法的调用明细。
二、一些初步尝试
2.1、正常trace命令流程
2.2、使用-E+多个类层级向下展开
一次Trace命令只会调用出一层方法耗时情况,那么在结果出来前应当是不知道哪个方法是耗时最长的,那么在不改变Trace底层逻辑的情况下,可以使用-E+ |来模拟到多层分析结果。例如:
2.2.1、使用Trace命令查看第一层调用情况
trace Main toPrint -n 5
2.2.2、将红框中的耗时最大的方法-的类名和方法名复制,写入命令中,然后再触发一次请求
trace -E Main|Main toPrint|toPrintD -n 5
可以看到,是可以实现多层展示的。
2.2.3、继续下钻
若需要继续下钻,则重复2.2.2的操作
2.2.4、总结
(本次案例结构简单,可能看上去不直观,可自行找复杂的场景试试)
这样做有两个不便之处:
- 需要多次动用复制粘贴快捷键,来复制到新的命令中
- 需要调用多次方法(但一般而言,调试过程中多调用几次,个人觉得影响不大)
三、源码分析
正所谓知己知彼方能百战不殆,接下来这部分通过分析源码,来了解shell上输入一个arthas命令执行从输入到输出,在这过程中arthas做了什么处理,怎么做到的。以jad java.lang.String为例。
这儿arthas已经是启动状态了,即arthas已经启动了监听器在监听命令行,就等着输入命令。
3.1、接收shell命令
首先会在com.taobao.arthas.core.shell.handlers.term.RequestHandler的accept方法,接收到该请求。参数line为输入的命令。
接着会调用handle方法,最终会走到ShellLineHandler的handle方法。
3.2、一些即时命令的处理&准备调用createJob
一些如jobs、fg等命令会直接处理返回,后续就不会创建job任务做处理。
其余情况,准备调用createJob方法。