文章目录
一、前言
在数字世界中,Java作为一种流行的编程语言,广泛应用于开发各种类型的应用程序。然而,在开发过程中,不可避免地会出现各种问题。本文将探讨一些用于诊断和排查Java问题的工具。
二、Java问题诊断和排查工具
1、JDK自带工具
在JDK的bin目录下有很多命令行工具:
可以看到各个工具的大小基本上都稳定在27kb左右,这个不是JDK开发团队刻意为之的,而是因为这些工具大多数是 jdk\lib\tools.jar 类库的一层薄包装而已,他们的主要功能代码是在tools类库中实现的。
命令行工具的好处是:当应用程序部署到生产环境后,无论是直接接触物理服务器还是远程telnet到服务器上都会受到限制。而借助tools.jar类库里面的接口,我们可以直接在应用程序中实现功能强大的监控分析功能。
2、常用命令
1、jps:查看本机java进程信息
2、jstack:打印线程的栈信息,制作 线程dump文件
3、jmap:打印内存映射信息,制作 堆dump文件
4、jstat:性能监控工具
5、jhat:内存分析工具,用于解析堆dump文件并以适合人阅读的方式展示出来
6、jconsole:简易的JVM可视化工具
7、jvisualvm:功能更强大的JVM可视化工具
8、javap:查看字节码
3、JAVA Dump:
JAVA Dump就是虚拟机运行时的快照,将虚拟机运行时的状态和信息保存到文件中,包括:
线程dump:包含所有线程的运行状态,纯文本格式
堆dump:包含所有堆对象的状态,二进制格式
3.1、jps
显示当前所有java进程pid的命令,我们可以通过这个命令来查看到底启动了几个java进程(因为每一个java程序都会独占一个java虚拟机实例),不过jps有个缺点是只能显示当前用户的进程id,要显示其他用户的还只能用linux的ps命令。
在这里插入
执行jps命令,会列出所有正在运行的java进程,其中jps命令也是一个java程序。前面的数字就是进程的id,这个id的作用非常大,后面会有相关介绍。
ps -l 输出应用程序main.class的完整package名或者应用程序jar文件完整路径名
jps -v 输出传递给JVM的参数
ps失效
我们在定位问题过程会遇到这样一种情况,用jps查看不到进程id,用ps -ef | grep java却能看到启动的java进程。
要解释这种现象,先来了解下jps的实现机制:
java程序启动后,会在目录/tmp/hsperfdata_{userName}/下生成几个文件,文件名就是java进程的pid,因此jps列出进程id就是把这个目录下的文件名列一下而已,至于系统参数,则是读取文件中的内容。
我们来思考下:如果由于磁盘满了,无法创建这些文件,或者用户对这些文件没有读的权限。又或者因为某种原因这些文件或者目录被清除,出现以上这些情况,就会导致jps命令失效。
如果jps命令失效,而我们又要获取pid,还可以使用以下两种方法:
1、top | grep java
2、ps -ef |grep java
3.2、jstack
主要用于生成指定进程当前时刻的线程快照,线程快照是当前java虚拟机每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是用于定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致长时间等待。
3.3、jmap
主要用于打印指定java进程的共享对象内存映射或堆内存细节。
堆Dump是反映堆使用情况的内存镜像,其中主要包括系统信息、虚拟机属性、完整的线程Dump、所有类和对象的状态等。一般在内存不足,GC异常等情况下,我们会去怀疑内存泄漏,这个时候就会去打印堆Dump。