原谅我的标题党,其实这些工具的确很厉害,之前其实介绍过一点相关的,是从我一次问题排查的过程中用到的,但是最近又有碰到一次排查问题,发现其实用 idea 直接 dump thread 是不现实的,毕竟服务器环境的没法这么操作,那就得用 Java 的那些工具了
jstack & jps
譬如 jstack,这个命令其实不能更简单了
看看 help 信息
用-l参数可以打出锁的额外信息,然后后面的 pid 就是进程 id 咯,机智的小伙伴会问了(就你这个小白才问这么蠢的问题🤦♂️),怎么看 Java 应用的进程呢
那就是 jps 了,命令也很简单,一般直接用 jps命令就好了,不过也可以 help 看一下
稍微解释下,-q是只显示进程 id,-m是输出给main 方法的参数,比如我在配置中加给参数
然后用 jps -m查看
-v加上小 v 的话就是打印 jvm 参数
还是有点东西,然后就继续介绍 jstack 了,然后我们看看 jstack 出来是啥,为了加点内容我加了个死锁
1 | public static void main(String[] args) throws InterruptedException { |
然后看看出来时怎么样的
1 | 2020-08-02 21:50:32 |
前面的信息其实上次就看过了,后面就可以发现有个死锁了,
上面比较长,把主要的截出来,就是这边的,这点就很强大了。
jmap
惯例还是看一下帮助信息
这个相对命令比较多,不过因为现在 dump 下来我们可能会用文件模式,然后将文件下载下来使用 mat 进行分析,所以可以使用jmap -dump:live,format=b,file=heap.bin <pid>
命令照着上面看的就是打印活着的对象,然后以二进制格式,文件名叫 heap.bin 然后最后就是进程 id,打印出来以后可以用 mat 打开
这样就可以很清晰的看到应用里的各种信息,jmap 直接在命令中还可以看很多信息,比如使用jmap -histo <pid>打印对象的实例数和对象占用的内存
jmap -finalizerinfo <pid> 打印正在等候回收的对象
小tips
对于一些应用内存已经占满了,jstack 和 jmap 可能会连不上的情况,可以使用-F参数强制打印线程或者 dump 文件,但是要注意这两者使用的用户必须与 java 进程启动用户一致,并且使用的 jdk 也要一致