一:通过命令排查:
有的时候在生产环境是无法使用Jprofiler等工具的,我们只能借助jdk提供的相关命令进行排查
top:使用Top命令排查CPU消耗很高的进程
top -H -p pid :查到进程消耗的CPU很高的情况下我们可以通过以下命令来定位到那个线程消耗的CPU高
转换16进制:因为java中查看线程号使用的是16进制我们需要将linux中的线程号转换为java中能够使用的16进制
print "%x" 95911 -> (执行后获取到执行16进制的pid是 176a7)
查看进行运行状态 ——》jstack 95891|grep 176a7 :使用 jstack 进程id|grep tid 转换成16进制后的数字,查看该线程是否运行
排查代码:jstack 95891|grep 176a7 -A20 -B20 (显示当前线程后面CPU消耗很高的线程的堆栈信息,)
二:Arthas排查
1,运行Arthas :java -jar arthas-boot.jar (选择加载一个java进程)
2,dashboard :使用 dashboard 来查看全局的性能监控
3,thread pid 的形式开查看具体线程内容(比如:thread 15)
4,反编译代码:可以使用jad工具进行反编译,查看具体哪里有问题 (比如:jad com.xuexi.test.handler.HandlerTask)
5,导出当前的内内存中的类的原代码:jad --source-only --lineNumber true com.xuexi.test.handler.HandlerTask >/tmp/HandlerTask.java
--lineNumber true 显示行数(默认true)
6,跟踪方法调用:trace com.xuexi.test.handler.HandlerTask execute (怀疑这个方法有问题,可以尝试用 trace 方法来进行调用一次)
7,修改原代码 :修改刚刚导出的类的原代码(vi /tmp/HandlerTask.java)(注意:推荐本地修改代码,编译好后再上传到服务器上)
查看类信息:sc -d com.xuexi.test.handler.HandlerTask
8,查找类加载器 :我们需要用替换类的类加载器对于我们修改后的原代码进行编译(sc -d com.xuexi.test.handler.HandlerTask | grep classLoaderHash)
9,热编译:通过类加载器将我们的类进行编译(mc -c 31cefde0 /tmp/HandlerTask.java [-d /tmp])
10,加载新类:编译后就可以在不重启的情况下加载新类,使用redefine命令重新加载新编译好的HandlerTask.class (redefine [-c 31cefde0] /tmp/com/xuexi/test/handler/HandlerTask.class)