您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > JAVA

Java 故障处理工具

时间:2019-11-12 09:43:16  来源:  作者:

1 JDK常用命令

1.1 jsp命令

jps虚拟机进程状态工具。具体的执行结果如下:

Java 故障处理工具

 

jps命令格式:

jps [options] [hostid]

jps的其他常用选项

Java 故障处理工具

 

命令格式中,如果需要查看远端机器上的进程,则需要填写对应hostid就好。具体的如下:

jps 10.**.**.148

1.2 jstat

用于监视虚拟机各种运行状态信息的命令行工具,它可以显示本地或者是远程虚拟机进程中的类装载,内存,垃圾收集,JIT编译等运行数据。jstat命令格式为:

jstat [ option vmid [ interval[s|ms] [count]]

其中vmid如果是本地进程,则vmid对应的为虚拟机进程号。如果是远程虚拟机进程,则对应的格式应该是:

[protocol:][//] vmid[@hostname[:port]/servername]

远程机器上的服务进程需要支持RMI,使用jstad工具可以很方便的简历RMI服务器。

参数interval和count表示间隔和次数。例如针对本地的进程查看其每隔一段时间对应的GC情况:

jstat -gc 3836 1000 20

执行结果如下:

Java 故障处理工具

 

每一列的说明如下:

Java 故障处理工具

 

jstat常见选项:

Java 故障处理工具

 

在查看下具体的JIT编译情况:

Java 故障处理工具

 

上面的各列表示:编译数量,失败数量,不可用数量,耗时,失败类型,失败方法

查看类装载情况:

Java 故障处理工具

 

上面的各列表示:加载class的数量,加载字节数,未加载类数量,未加载占用空间,耗时

通过开始的jstat命令格式可以知道,jstat支持远程监控,具体的监控需要依赖于jstatd命令。jstatd命令需要现在远程机器上开启一个rmi进程。用于支持远端连接。

在任意目录下创建一个.policy文件:jstatd.all.policy

grant codebase "file:${JAVA.home}/../lib/tools.jar" {
 permission java.security.AllPermission;
};

然后在下执行(这里是当前目录下直接执行的,java.security.policy执行你的文件所在的目录地址也是可以的):

jstatd -J-Djava.security.policy=jstatd.all.policy -J-Djava.rmi.server.hostname=10.**.**.148

在本地进行调用,查看远端上某一进程的GC情况:

Java 故障处理工具

 

其中1099端口为默认端口

1.3 jinfo

jinfo的作用是实时查看和调整虚拟机各项参数配置。命令基本格式:

jinfo [option] pid

仅支持本地的进程修改。基本上的格式为

jinfo -flag [+|-] name
jinfo -flag name = value

jinfo还支持打印当前的System.getProperties()中的信息,具体的如下:

Java 故障处理工具

 

1.4 jmap

jmap是堆转存储快照的命令。当然也可以不用这个,可以在应用启动时增加-XX:+HeapDumpOnOutOfMemoryError参数。jmap命令格式

jmap [option] vmid

option的主要选项

Java 故障处理工具

 

具体的截图如下:

Java 故障处理工具

 

1.5 jhat

jhat命令是和jmap命令搭配使用的,主要使用来分析堆存储快照的。jhat命令太过简陋,针对上面生成的dump文件,分析如下:

Java 故障处理工具

 

打开浏览器访问7000端口:

Java 故障处理工具

 

1.6 jstack

jstack命令用于生成虚拟机当前时刻线程快照。线程快照是当前虚拟机内每一条线程正在执行的方法堆栈的集合。主要用于定位线程长时间停顿(线程死锁,死循环,寻求外部资源等)。jstack名称格式为:

jstack [option] vmid

参数主要选项:

Java 故障处理工具

 

本地编写一个循环,每输出一段日志后就休眠1s.对应的堆栈信息如下:

Java 故障处理工具

 

可以看到截图中提示无死锁

No deadlocks found.

截图中并无死锁。所有的线程基本都是Blocked。那么应该是线程都属于休眠状态。具体的看:

Thread 6915: (state = BLOCKED)
 - java.lang.Thread.sleep(long) @bci=0 (Compiled frame; information may be imprecise)
 - com.jvm.study.test.TestMain.main(java.lang.String[]) @bci=22, line=10 (Interpreted frame)

有sleep操作。线程休眠等待唤醒。

编写一段死锁的代码,通过jstack来分析具体的问题:

public class TestMain {

 private static final Object lock1 = new Object();
 private static final Object lock2 = new Object();

 public static void main(String[] args) throws Exception{
 Thread t1 = new Thread(new Runnable() {
 public void run() {
 try {
 synchronized (lock1){
 System.out.println(Thread.currentThread().getName());
 TimeUnit.SECONDS.sleep(1);
 synchronized (lock2){
 System.out.println(Thread.currentThread().getName());
 }
 }
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 }
 });
 Thread t2 = new Thread(new Runnable() {
 public void run() {
 try {
 synchronized (lock2){
 System.out.println(Thread.currentThread().getName());
 TimeUnit.SECONDS.sleep(1);
 synchronized (lock1){
 System.out.println(Thread.currentThread().getName());
 }
 }
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 }
 });
 t1.setName("mythread1");
 t2.setName("mythread2");
 t1.start();
 t2.start();
 }
}

说明:在启动后,t1线程持有了lock1后,在休眠1ms后,在申请获取lock2。而t2线程启动后,先持有lock2,在休眠1ms后,申请lock1。这个时候lock1已经被t1持有。造成相互等待争夺的情况。线程死锁。通过jstack查看后如下:

2019-11-11 13:25:59
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.131-b11 mixed mode):

"Attach Listener" #13 daemon prio=9 os_prio=31 tid=0x00007f8182802800 nid=0x1107 waiting on condition [0x0000000000000000]
 java.lang.Thread.State: RUNNABLE

"DestroyJavaVM" #12 prio=5 os_prio=31 tid=0x00007f818206d000 nid=0x1b03 waiting on condition [0x0000000000000000]
 java.lang.Thread.State: RUNNABLE

"mythread2" #11 prio=5 os_prio=31 tid=0x00007f8182011000 nid=0x5103 waiting for monitor entry [0x000070000a6fb000]
 java.lang.Thread.State: BLOCKED (on object monitor)
 at com.jvm.study.test.TestMain$2.run(TestMain.java:33)
 - waiting to lock <0x00000007957843b0> (a java.lang.Object)
 - locked <0x00000007957843c0> (a java.lang.Object)
 at java.lang.Thread.run(Thread.java:748)

"mythread1" #10 prio=5 os_prio=31 tid=0x00007f8182064000 nid=0x4f03 waiting for monitor entry [0x000070000a5f8000]
 java.lang.Thread.State: BLOCKED (on object monitor)
 at com.jvm.study.test.TestMain$1.run(TestMain.java:18)
 - waiting to lock <0x00000007957843c0> (a java.lang.Object)
 - locked <0x00000007957843b0> (a java.lang.Object)
 at java.lang.Thread.run(Thread.java:748)

"Service Thread" #9 daemon prio=9 os_prio=31 tid=0x00007f81830e0000 nid=0x4b03 runnable [0x0000000000000000]
 java.lang.Thread.State: RUNNABLE

"C1 CompilerThread2" #8 daemon prio=9 os_prio=31 tid=0x00007f81830d5000 nid=0x4903 waiting on condition [0x0000000000000000]
 java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #7 daemon prio=9 os_prio=31 tid=0x00007f81830d4000 nid=0x4703 waiting on condition [0x0000000000000000]
 java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #6 daemon prio=9 os_prio=31 tid=0x00007f8181883800 nid=0x4503 waiting on condition [0x0000000000000000]
 java.lang.Thread.State: RUNNABLE

"Monitor Ctrl-Break" #5 daemon prio=5 os_prio=31 tid=0x00007f8181882000 nid=0x4303 runnable [0x0000700009fe6000]
 java.lang.Thread.State: RUNNABLE
 at java.net.SocketInputStream.socketRead0(Native Method)
 at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
 at java.net.SocketInputStream.read(SocketInputStream.java:171)
 at java.net.SocketInputStream.read(SocketInputStream.java:141)
 at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
 at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
 at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
 - locked <0x0000000795708388> (a java.io.InputStreamReader)
 at java.io.InputStreamReader.read(InputStreamReader.java:184)
 at java.io.BufferedReader.fill(BufferedReader.java:161)
 at java.io.BufferedReader.readLine(BufferedReader.java:324)
 - locked <0x0000000795708388> (a java.io.InputStreamReader)
 at java.io.BufferedReader.readLine(BufferedReader.java:389)
 at com.intellij.rt.execution.Application.AppMainV2$1.run(AppMainV2.java:64)

"Signal Dispatcher" #4 daemon prio=9 os_prio=31 tid=0x00007f8182002800 nid=0x4103 runnable [0x0000000000000000]
 java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=31 tid=0x00007f8183010000 nid=0x3003 in Object.wait() [0x0000700009d5d000]
 java.lang.Thread.State: WAITING (on object monitor)
 at java.lang.Object.wait(Native Method)
 - waiting on <0x0000000795588ec8> (a java.lang.ref.ReferenceQueue$Lock)
 at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
 - locked <0x0000000795588ec8> (a java.lang.ref.ReferenceQueue$Lock)
 at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
 at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)

"Reference Handler" #2 daemon prio=10 os_prio=31 tid=0x00007f818300d800 nid=0x2e03 in Object.wait() [0x0000700009c5a000]
 java.lang.Thread.State: WAITING (on object monitor)
 at java.lang.Object.wait(Native Method)
 - waiting on <0x0000000795586b68> (a java.lang.ref.Reference$Lock)
 at java.lang.Object.wait(Object.java:502)
 at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
 - locked <0x0000000795586b68> (a java.lang.ref.Reference$Lock)
 at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

"VM Thread" os_prio=31 tid=0x00007f8181845800 nid=0x2c03 runnable

"GC task thread#0 (ParallelGC)" os_prio=31 tid=0x00007f8183007000 nid=0x2403 runnable

"GC task thread#1 (ParallelGC)" os_prio=31 tid=0x00007f8183007800 nid=0x2603 runnable

"GC task thread#2 (ParallelGC)" os_prio=31 tid=0x00007f8183008000 nid=0x2803 runnable

"GC task thread#3 (ParallelGC)" os_prio=31 tid=0x00007f8183009000 nid=0x2a03 runnable

"VM Periodic Task Thread" os_prio=31 tid=0x00007f818282a000 nid=0x4d03 waiting on condition

JNI global references: 33


Found one Java-level deadlock:
=============================
"mythread2":
 waiting to lock monitor 0x00007f81828196b8 (object 0x00000007957843b0, a java.lang.Object),
 which is held by "mythread1"
"mythread1":
 waiting to lock monitor 0x00007f818281c158 (object 0x00000007957843c0, a java.lang.Object),
 which is held by "mythread2"

Java stack information for the threads listed above:
===================================================
"mythread2":
 at com.jvm.study.test.TestMain$2.run(TestMain.java:33)
 - waiting to lock <0x00000007957843b0> (a java.lang.Object)
 - locked <0x00000007957843c0> (a java.lang.Object)
 at java.lang.Thread.run(Thread.java:748)
"mythread1":
 at com.jvm.study.test.TestMain$1.run(TestMain.java:18)
 - waiting to lock <0x00000007957843c0> (a java.lang.Object)
 - locked <0x00000007957843b0> (a java.lang.Object)
 at java.lang.Thread.run(Thread.java:748)

Found 1 deadlock.

可以看到,在最后有一个死锁。

Java 故障处理工具

 

t2线程在等待

waiting to lock <0x00000007957843b0> (a java.lang.Object)

t2持有的锁是

locked <0x00000007957843c0> (a java.lang.Object)

t1线程在等待

waiting to lock <0x00000007957843c0> (a java.lang.Object)

t1持有的锁是

locked <0x00000007957843b0> (a java.lang.Object)

相互在等待对方持有的锁。通过上面可以找到死锁的原因,通过lock a java.lang.Object对象出现死锁。

2 JDK可视化工具

2.1 JConsole

jconsole是一种基于JMX的可视化监视,管理工具。它管理部分的功能是针对JMX MBean进行管理。启动JConsole:

Java 故障处理工具

 

同样的,选择本地进程,通过JConsole来查看是否有死锁:

Java 故障处理工具

 

选择好线上后,点击检查死锁,就会发现有相应的提示如:

Java 故障处理工具

 

JConsole可以观察内存,线程,类加载数等各个维度的数据.

2.2 VisualVM

VisualVM是目前为止JDK发布的功能最强大的运行监控和故障处理工具。VisualVM可以做到:

1 显示虚拟机进程以及进程的配置,环境信息
2 监视应用程序的CPU,GC,堆,方法区以及线程的信息
3 dump和分析堆快照
4 方法级的程序运行性能分析

启动VisualVM: 执行jvisualvm(mac下)

Java 故障处理工具

 

VisualVM可以根据需要安装不同的插件,每个插件的关注点都不同,有的主要监控GC,有的主要监控内存,有的监控线程等。选择工具 -> 插件:

Java 故障处理工具

 

继续针对上面的死锁来通过VisualVM进行检查:

Java 故障处理工具

 

通过点击线下,找到对应的thread2后,提示检查到死锁。

这里只是简单的介绍,后面针对性能调优时会有介绍使用



Tags:Java   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
文章目录 如何理解面向对象编程? JDK 和 JRE 有什么区别? 如何理解Java中封装,继承、多态特性? 如何理解Java中的字节码对象? 你是如何理解Java中的泛型的? 说说泛型应用...【详细内容】
2021-12-24  Tags: Java  点击:(5)  评论:(0)  加入收藏
文章目录1、Quartz1.1 引入依赖<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.2</version></dependency>...【详细内容】
2021-12-22  Tags: Java  点击:(12)  评论:(0)  加入收藏
1 前言ObjectiveSQL 是一个Java ORM 框架,它不仅是Active Record 模式在Java 中的应用,同时还针对复杂SQL 编程提供近乎完美的解决方案,使得Java 代码与SQL 语句有机的结合,改变...【详细内容】
2021-12-13  Tags: Java  点击:(14)  评论:(0)  加入收藏
本系列为 Netty 学习笔记,本篇介绍总结Java NIO 网络编程。Netty 作为一个异步的、事件驱动的网络应用程序框架,也是基于NIO的客户、服务器端的编程框架。其对 Java NIO 底层...【详细内容】
2021-12-07  Tags: Java  点击:(17)  评论:(0)  加入收藏
流为什么动不动就说 io 流? 这个“流”是什么意思呢?流这个词,也常常出现在电竞选手的领域。大家都说,哦,这个队伍经常上去卖人头来取得局面优势的这种打法,叫献祭流。而到了 Java...【详细内容】
2021-11-15  Tags: Java  点击:(33)  评论:(0)  加入收藏
1. 字符串有整型的相互转换String a = String.valueOf(2); //integer to numeric stringint i = Integer.parseInt(a); //numeric string to an int 2. 向文件末尾添加内容B...【详细内容】
2021-10-13  Tags: Java  点击:(92)  评论:(0)  加入收藏
负载均衡是将客户端请求访问,通过提前约定好的规则转发给各个server。其中有好几个种经典的算法,下面我们用Java实现这几种算法。 轮询算法轮询算法按顺序把每个新的连接请求...【详细内容】
2021-09-27  Tags: Java  点击:(52)  评论:(0)  加入收藏
1 背景近日在给公司同事分享Arthas 工具使用时候,被它强悍的功能震撼到了就好奇研究了下它的原理及底层实现,其实它是通过Java agent 来实现的,也就深入地学习了一下Java agent...【详细内容】
2021-09-09  Tags: Java  点击:(67)  评论:(0)  加入收藏
近日浏览网上一些图片提取文字的网站,觉得甚是有趣,花费半日也做了个在线图片识别程序,完成了两个技术方案的选择,一是 tesseract + Python flask的方案实现,二是 tesseract + Sp...【详细内容】
2021-09-07  Tags: Java  点击:(81)  评论:(0)  加入收藏
Java String的判空方法是Java开发中的一个很基础的方法,下面列举了一些常用的方法。 方法一:效率高,也是最常用的方法。if(s == null || s.length() <= 0) 方法二:也是常看到的...【详细内容】
2021-09-03  Tags: Java  点击:(124)  评论:(0)  加入收藏
▌简易百科推荐
面向对象的特征之一封装 面向对象的特征之二继承 方法重写(override/overWrite) 方法的重载(overload)和重写(override)的区别: 面向对象特征之三:多态 Instanceof关键字...【详细内容】
2021-12-28  顶顶架构师    Tags:面向对象   点击:(2)  评论:(0)  加入收藏
一、Redis使用过程中一些小的注意点1、不要把Redis当成数据库来使用二、Arrays.asList常见失误需求:把数组转成list集合去处理。方法:Arrays.asList 或者 Java8的stream流式处...【详细内容】
2021-12-27  CF07    Tags:Java   点击:(3)  评论:(0)  加入收藏
文章目录 如何理解面向对象编程? JDK 和 JRE 有什么区别? 如何理解Java中封装,继承、多态特性? 如何理解Java中的字节码对象? 你是如何理解Java中的泛型的? 说说泛型应用...【详细内容】
2021-12-24  Java架构师之路    Tags:JAVA   点击:(5)  评论:(0)  加入收藏
大家好!我是老码农,一个喜欢技术、爱分享的同学,从今天开始和大家持续分享JVM调优方面的经验。JVM调优是个大话题,涉及的知识点很庞大 Java内存模型 垃圾回收机制 各种工具使用 ...【详细内容】
2021-12-23  小码匠和老码农    Tags:JVM调优   点击:(12)  评论:(0)  加入收藏
前言JDBC访问Postgresql的jsonb类型字段当然可以使用Postgresql jdbc驱动中提供的PGobject,但是这样在需要兼容多种数据库的系统开发中显得不那么通用,需要特殊处理。本文介绍...【详细内容】
2021-12-23  dingle    Tags:JDBC   点击:(13)  评论:(0)  加入收藏
Java与Lua相互调用案例比较少,因此项目使用需要做详细的性能测试,本内容只做粗略测试。目前已完成初版Lua-Java调用框架开发,后期有时间准备把框架进行抽象,并开源出来,感兴趣的...【详细内容】
2021-12-23  JAVA小白    Tags:Java   点击:(11)  评论:(0)  加入收藏
Java从版本5开始,在 java.util.concurrent.locks包内给我们提供了除了synchronized关键字以外的几个新的锁功能的实现,ReentrantLock就是其中的一个。但是这并不意味着我们可...【详细内容】
2021-12-17  小西学JAVA    Tags:JAVA并发   点击:(11)  评论:(0)  加入收藏
一、概述final是Java关键字中最常见之一,表示“最终的,不可更改”之意,在Java中也正是这个意思。有final修饰的内容,就会变得与众不同,它们会变成终极存在,其内容成为固定的存在。...【详细内容】
2021-12-15  唯一浩哥    Tags:Java基础   点击:(17)  评论:(0)  加入收藏
1、问题描述关于java中的日志管理logback,去年写过关于logback介绍的文章,这次项目中又优化了下,记录下,希望能帮到需要的朋友。2、解决方案这次其实是碰到了一个问题,一般的情况...【详细内容】
2021-12-15  软件老王    Tags:logback   点击:(19)  评论:(0)  加入收藏
本篇文章我们以AtomicInteger为例子,主要讲解下CAS(Compare And Swap)功能是如何在AtomicInteger中使用的,以及提供CAS功能的Unsafe对象。我们先从一个例子开始吧。假设现在我们...【详细内容】
2021-12-14  小西学JAVA    Tags:JAVA   点击:(22)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条