jdk监控和故障处理工具

主要jdk诊断命令

jps (JVM Process Status): 类似 UNIX 的 ps 命令。用户查看所有 Java 进程的启动类、传入参数和 Java 虚拟机参数等信息;----常用
jstat( JVM Statistics Monitoring Tool): 用于收集 HotSpot 虚拟机各方面的运行数据; ----常用
jinfo (Configuration Info for Java) : Configuration Info forJava,显示虚拟机配置信息;
jmap (Memory Map for Java) :生成堆转储快照;----常用
jhat (JVM Heap Dump Browser ) : 用于分析 heapdump 文件,它会建立一个 HTTP/HTML 服务器,让用户可以在浏览器上查看分析结果;
jstack (Stack Trace for Java):生成虚拟机当前时刻的线程快照,线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合。

1、jps:查看所有 Java 进程
jps -l:输出主类的全名,如果进程执行的是 Jar 包,输出 Jar 路径。
在这里插入图片描述
jps -v:输出虚拟机每个进程启动时 JVM 参数。
在这里插入图片描述
2、jstat: 监视虚拟机各种运行状态信息
jstat(JVM Statistics Monitoring Tool) 使用于监视虚拟机各种运行状态信息的命令行工具。 它可以显示本地或者远程(需要远程主机提供 RMI 支持)虚拟机进程中的类信息、内存、垃圾收集、JIT 编译等运行数据,在没有 GUI,只提供了纯文本控制台环境的服务器上,它将是运行期间定位虚拟机性能问题的首选工具。

jstat 命令使用格式:

jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

比如 jstat -gc -h3 7936 1000 10表示分析进程 id 为 31736 的 gc 情况,每隔 1000ms 打印一次记录,打印 10 次停止,每 3 行后打印指标头部。
在这里插入图片描述
常见的 option 如下:

  • jstat -class vmid :显示 ClassLoader 的相关信息;
  • jstat -compiler vmid :显示 JIT 编译的相关信息;
  • jstat -gc vmid :显示与 GC 相关的堆信息;
  • jstat -gccapacity vmid :显示各个代的容量及使用情况;
  • jstat -gcnew vmid :显示新生代信息;
  • jstat -gcnewcapcacity vmid :显示新生代大小与使用情况;
  • jstat -gcold vmid :显示老年代和永久代的信息;
  • jstat -gcoldcapacity vmid :显示老年代的大小;
  • jstat -gcpermcapacity vmid :显示永久代大小;
  • jstat -gcutil vmid :显示垃圾收集信息;

3、jinfo: 实时地查看和调整虚拟机各项参数
jinfo vmid :输出当前 jvm 进程的全部参数和系统属性 (第一部分是系统的属性,第二部分是 JVM 的参数)。
在这里插入图片描述
jinfo -flag name vmid :输出对应名称的参数的具体值。比如输出 MaxHeapSize。

在这里插入图片描述
使用 jinfo 可以在不重启虚拟机的情况下,可以动态的修改 jvm 的参数。尤其在线上的环境特别有用,请看下面的例子:
jinfo -flag [+|-]name vmid 开启或者关闭对应名称的参数。
在这里插入图片描述
4、jmap:生成堆转储快照
jmap(Memory Map for Java)命令用于生成堆转储快照。 如果不使用 jmap 命令,要想获取 Java 堆转储,可以使用 “-XX:+HeapDumpOnOutOfMemoryError” 参数,可以让虚拟机在 OOM 异常出现之后自动生成 dump 文件,Linux 命令下可以通过 kill -3 发送进程退出信号也能拿到 dump 文件。

jmap 的作用并不仅仅是为了获取 dump 文件,它还可以查询 finalizer 执行队列、Java 堆和永久代的详细信息,如空间使用率、当前使用的是哪种收集器等。和jinfo一样,jmap有不少功能在 Windows 平台下也是受限制的。

示例:将指定应用程序的堆快照输出到D盘。后面,可以通过 jhat、Visual VM 等工具分析该堆文件。

C:\jdk8_4\bin>jmap -dump:format=b,file=D:test.hprof 7936
Dumping heap to D:\test.hprof ...
Heap dump file created

5、jstack :生成虚拟机当前时刻的线程快照
jstack(Stack Trace for Java)命令用于生成虚拟机当前时刻的线程快照。线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合.

生成线程快照的目的主要是定位线程长时间出现停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等都是导致线程长时间停顿的原因。线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做些什么事情,或者在等待些什么资源。
下面是一个线程死锁的代码。我们下面会通过 jstack 命令进行死锁检查,输出死锁信息,找到发生死锁的线程。

public class DeadLockDemo {
    private static Object resource1 = new Object();//资源 1
    private static Object resource2 = new Object();//资源 2

    public static void main(String[] args) {
        new Thread() {
            @Override
            public void run() {
                synchronized (resource1) {
                    System.out.println(Thread.currentThread() + "get resource1");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread() + "waiting get resource2");
                    synchronized (resource2) {
                        System.out.println(Thread.currentThread() + "get resource2");
                    }
                }
            }
        }.start();

        new Thread() {
            @Override
            public void run() {
                synchronized (resource2) {
                    System.out.println(Thread.currentThread() + "get resource2");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread() + "waiting get resource1");
                    synchronized (resource1) {
                        System.out.println(Thread.currentThread() + "get resource1");
                    }
                }
            }
        }.start();
    }
}

Output

Thread[Thread-1,5,main]get resource2
Thread[Thread-0,5,main]get resource1
Thread[Thread-1,5,main]waiting get resource1
Thread[Thread-0,5,main]waiting get resource2

为什么死锁:线程 A 通过 synchronized (resource1) 获得 resource1 的监视器锁,然后通过Thread.sleep(1000);让线程 A 休眠 1s 为的是让线程 B 得到执行然后获取到 resource2 的监视器锁。线程 A 和线程 B 休眠结束了都开始企图请求获取对方的资源,然后这两个线程就会陷入互相等待的状态,这也就产生了死锁。

通过 jstack 命令分析(关键部分):

C:\jdk8_4\bin>jps -l
8016
2740 org.jetbrains.jps.cmdline.Launcher
9588 sun.tools.jps.Jps
10156 com.channel.kuaiqian.DeadLockDemo

C:\jdk8_4\bin>jstack 10156

输出的部分内容如下:

Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x000000000338caf8 (object 0x000000076ba69c20, a java.lang.Object),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x000000000338a528 (object 0x000000076ba69c30, a java.lang.Object),
  which is held by "Thread-1"

Java stack information for the threads listed above:
===================================================
"Thread-1":
        at com.channel.kuaiqian.DeadLockDemo$2.run(DeadLockDemo.java:44)
        - waiting to lock <0x000000076ba69c20> (a java.lang.Object)
        - locked <0x000000076ba69c30> (a java.lang.Object)
"Thread-0":
        at com.channel.kuaiqian.DeadLockDemo$1.run(DeadLockDemo.java:26)
        - waiting to lock <0x000000076ba69c30> (a java.lang.Object)
        - locked <0x000000076ba69c20> (a java.lang.Object)

Found 1 deadlock.

在这里插入图片描述
可以看到 jstack 命令已经帮我们找到发生死锁的线程的具体信息。

JDK 可视化分析工具

6、JConsole:Java 监视与管理控制台
JConsole 是基于 JMX 的可视化监视、管理工具。可以很方便的监视本地及远程服务器的 java 进程的内存使用情况。你可以在控制台输出console命令启动或者在 JDK 目录下的 bin 目录找到jconsole.exe然后双击启动。
连接 Jconsole
在这里插入图片描述
如果需要使用 JConsole 连接远程进程,可以在远程 Java 程序启动时加上下面这些参数:

-Djava.rmi.server.hostname=外网访问 ip 地址 
-Dcom.sun.management.jmxremote.port=60001   //监控的端口号
-Dcom.sun.management.jmxremote.authenticate=false   //关闭认证
-Dcom.sun.management.jmxremote.ssl=false

在使用 JConsole 连接时,远程进程地址如下:

外网访问 ip 地址:60001 

查看 Java 程序概况
在这里插入图片描述
内存监控
JConsole 可以显示当前内存的详细信息。不仅包括堆内存/非堆内存的整体信息,还可以细化到 eden 区、survivor 区等的使用情况,如下图所示。

点击右边的“执行 GC(G)”按钮可以强制应用程序执行一个 Full GC。
在这里插入图片描述
线程监控
类似我们前面讲的 jstack 命令,不过这个是可视化的。

最下面有一个"检测死锁 (D)"按钮,点击这个按钮可以自动为你找到发生死锁的线程以及它们的详细信息 。
在这里插入图片描述
7、MAT
MAT 可以离线分享dump文件中, 堆栈信息。常用于找大对象、堆栈使用情况、内存溢出、内存泄漏等情况。
通用流程:jmap 导出堆栈信息、mat分析快照中的内存使用情况
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值