JAVA 问题排查
转自:https://www.pdai.tech/md/interview/x-interview.html#54-%E9%97%AE%E9%A2%98%E6%8E%92%E6%9F%A5
常见的 Linux 定位问题的工具?
文本操作:
文本查找 - grep
文本分析 - awk
文本处理 - sed
文件操作:
文件监听 - tail
文件查找 - find
网络和进程:
网络接口 - ifconfig
防火墙 - iptables -L
路由表 - route -n
netstat
其他常用:
进程 ps -ef | grep java
分区大小 dh -f
内存 free -m
硬盘大小 fdisk -l | grep Disk
top
环境变量 env
JDK 自带的定位问题的工具?
jps : jps是jdk提供的一个查看当前java进程的小工具, 可以看做是JavaVirtual Machine Process Status Tool的缩写。
jps -l # 输出完全的包名,应用主类名, jar的完全路径
jstack: jstack是jdk自带的线程堆栈分析工具,使用该命令可以查看或导出 Java 应用程序中线程堆栈信息
# 基本 jstack 2815 jstack -m 2815 # java和native c/c++框架的所有栈信息 jstack -l 2815 # 额外的锁信息列表,查看是否死锁
jinfo: jinfo 是 JDK 自带的命令,可以用来查看正在运行的 java 应用程序的扩展参数,包括Java System属性和JVM命令行参数;也可以动态的修改正在运行的 JVM 一些参数。当系统崩溃时,jinfo可以从core文件里面知道崩溃的Java应用程序的配置信息
jinfo 2815 # 输出当前 jvm 进程的全部参数和系统属性
jmap:命令jmap是一个多功能的命令。它可以生成 java 程序的 dump 文件, 也可以查看堆内对象示例的统计信息、查看 ClassLoader 的信息以及 finalizer 队列。
# 查看堆的情况 jmap -heap 2815 # dump jmap -dump:live,format=b,file=/tmp/heap2.bin 2815
jstat: jstat参数众多,但是使用一个就够了
jstat -gcutil 2815 1000
如何使用在线调试工具 Arthas?
查看最繁忙的线程,以及是否有阻塞情况发生?
场景:我想看下查看最繁忙的线程,以及是否有阻塞情况发生? 常规查看线程,一般我们可以通过 top 等系统命令进行查看,但是那毕竟要很多个步骤,很麻烦。
thread -n 3 # 查看最繁忙的三个线程栈信息 thread # 以直观的方式展现所有的线程情况 thread -b #找出当前阻塞其他线程的线程
确认某个类是否已被系统加载?
场景:我新写了一个类或者一个方法,我想知道新写的代码是否被部署了?
# 即可以找到需要的类全路径,如果存在的话 sc *MyServlet # 查看这个某个类所有的方法 sm pdai.tech.servlet.TestMyServlet * # 查看某个方法的信息,如果存在的话 sm pdai.tech.servlet.TestMyServlet testMethod
如何查看一个 class 类的源码信息?
场景:我新修改的内容在方法内部,而上一个步骤只能看到方法,这时候可以反编译看下源码
# 直接反编译出java 源代码,包含一此额外信息的
jad pdai.tech.servlet.TestMyServlet
如何跟踪某个方法的返回值、入参?
场景:我想看下我新加的方法在线运行的参数和返回值?
# 同时监控入参,返回值,及异常 watch pdai.tech.servlet.TestMyServlet testMethod "{params, returnObj, throwExp}" -e -x 2
如何看方法调用栈的信息?
场景:我想看下某个方法的调用栈的信息?
stack pdai.tech.servlet.TestMyServlet testMethod
运行此命令之后需要即时触发方法才会有响应的信息打印在控制台上
找到最耗时的方法调用?
场景:testMethod这个方法入口响应很慢,如何找到最耗时的子调用?
# 执行的时候每个子调用的运行时长,可以找到最耗时的子调用。
stack pdai.tech.servlet.TestMyServlet testMethod
运行此命令之后需要即时触发方法才会有响应的信息打印在控制台上,然后一层一层看子调用
如何临时更改代码运行?
场景:我找到了问题所在,能否线上直接修改测试,而不需要在本地改了代码后,重新打包部署,然后重启观察效果?
# 先反编译出class源码 jad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.java # 然后使用外部工具编辑内容 mc /tmp/UserController.java -d /tmp # 再编译成class # 最后,重新载入定义的类,就可以实时验证你的猜测了 redefine /tmp/com/example/demo/arthas/user/UserController.class
如上,是直接更改线上代码的方式,但是一般好像是编译不成功的。所以,最好是本地ide编译成 class文件后,再上传替换为好!
总之,已经完全不用重启和发布了!这个功能真的很方便,比起重启带来的代价,真的是不可比的。比如,重启时可能导致负载重分配,选主等等问题,就不是你能控制的了。
我如何测试某个方法的性能问题?
monitor -c 5 demo.MathGame primeFactors
复杂综合类型问题的定位思路?