java基础教程虚拟机性能分析和故障解决工具【命令行(jps、jstat、jstack)】

简介: java基础教程虚拟机性能分析和故障解决工具【命令行(jps、jstat、jstack)】

java基础教程虚拟机性能分析和故障解决工具

--------------作用:帮助判断cpu占用率过高-->死循环、死锁、内存泄露、内存溢出等等问题。


 

需要掌握

 jps 查看进程ID

  命令:jps

jstat 实时查看java进程运行的数据情况,可以判断是否内存泄露或者内存溢出的情况

  命令:jstat -gc 进程IDpid号)  或者 jstat -gcutil 进程ID

jstack ,查看或导出 Java 应用程序中线程堆栈信息,可以判断cpu占用率过高、死循环、死锁的情况

  命令:jstack -l 进程ID

 

常识或需要储备知识在文章最后~

 

 

一、常用工具详情:

1、jps (JVM Process Status Tool)

列出当前运行的所有java进程的ID

 

1):疑惑- wins 不是有任务管理器可以查看所有的进程,为啥还要jps?

答:虽然windows任务管理器可以查看所有的进程,是因为当不止一个java进程时,使用win10的任务管理器,很难区分他们;而且win10的工具只能看到进程,看不到线程,所以需要其他工具

 

2):jps 测试案例:



package jps;
import java.io.IOException;
/**
 * ❀掌握:使用 jps命令查看java进程的ID 
 * 命令:jps
 * 直接输入jps (相当于 jps -V )
 * 
 * 
 * 
命令格式: jps[options][hostid]
第一个参数options   [-mlvV]可以任意组合使用
第二个参数:hostid
主机或者是服务器的ip,如果不指定,就默认为当前的主机或者是服务器。
注意:如果需要查看其他机器上的jvm进程,需要在待查看机器上启动jstatd。
 * 
 * jps + 
 * -q: 显示进程ID
 * -m: 显示进程ID,主类名称,以及传入main方法的参数
 * -l: 显示进程ID,主类全名【全限定名】
 * -v: 显示进程ID,主类名称,以及传入jvm的参数
 * -V: 显示进程ID,主类名称[❀]
 * @author Huangyujun
 *
 *-Xmn8m 指定年轻代内存大小
 */
public class jpsDemo {
    public static void main(String[] args) throws IOException {
        System.out.println("jps");
        System.in.read();
    }
}


打开终端查看:

449.png


测试 jps -m 命令前需要先设置面方法传递参数:

----------【具体步骤】在自己书写的测试类,右键->Run as -> Run Configurations… ->


49.png


2、jstat(JVM Statistics Monitoring Tool)

查看虚拟机运行数据------类装载、内存、垃圾收集、JIT编译 -----内存泄露或者内存溢出的判断使用命令之前需要给虚拟机设置参数

---因为控制台输入gc日志的前提:配置一下jvm的参数

例如:-Xms20M -Xmx20M -Xmn10M -XX:+UseSerialGC -XX:+PrintGCDetails -verbose:gc -XX:SurvivorRatio=8

 * -Xms20M 堆的初始容量     -Xmx20M 堆的最大容量    -Xmn10M 堆中年轻(新生)代的大小

 * -XX:+UseSerialGC 指定垃圾收集器SerialGC(串型垃圾回收器)   -XX:+PrintGCDetails 打印内存中GC的行为

   -verbose:gc 显示GC的情况        

 * -XX:ServivorRatio=8   设置 New Generation新生代中的 Eden区与Servivor区比例是8:1

 

命令: jstat -gc 进程ID  或者 jstat -gcutil 进程ID   判断是否内存泄露或者内存溢出 [这个需要懂点内存jvm收集机制]:

  可以看文章(里边有演示怎么判断)--或者那本经典的书《深入理解Java虚拟机》;文章:《奇怪的GC (Allocation Failure)日志 - 简书 (jianshu.io)》   

 

案例:


package jstat;
import java.io.IOException;
/**
 * -gc 选项:垃圾收集的堆统计信息
S0C、S1C:幸存区容量                                                                S0C:当前幸存者空间0容量(kB)    S1C:当前生存空间1的容量(kB)
S0U、S1U:❀堆内存中幸存区使用的容量                                      S0U:幸存者空间0使用大小(kB)     S1U:幸存者空间1使用大小(kB)
EC、EU:伊甸园容量   伊甸园使用的容量                              EC:当前伊甸园空间容量(kB)          EU:伊甸园空间使用大小(kB)
OC、OU:❀老年代容量、老年代使用的容量                              OC:当前的老年代容量(kB)              OU:老年代使用大小(kB)
方法区的使用情况:MC、MU:元空间容量、元空间使用的容量                   MC:元空间容量(kB)                          MU:元空间使用大小(kB)
压缩类的情况:CCSC:压缩的类空间容量(kB) CCSU:使用的压缩类空间(kB)
● 垃圾回收:●
● YGC:新生代垃圾收集事件的数量
● YGCT:新生代垃圾回收时间
● FGC:完整GC事件的数量
● FGCT:完整的垃圾收集时间
● GCT:总垃圾收集时间
==================================================
jstat -gc 线程ID 
jstat -gcutil 线程ID
■ gc 和 gcutil 区别:gc显示的是大小, gcutil 显示的是占比
===================================================
 * @author Huangyujun 
 * -Xms20M -Xmx20M -Xmn10M -XX:+UseSerialGC -XX:+PrintGCDetails -verbose:gc -XX:SurvivorRatio=8 
 * -Xms20M -Xmx20M -Xmn10M -XX:+UseSerialGC -XX:+PrintGCDetails -verbose:gc 
 * -Xms20M 堆的初始容量     -Xmx20M 堆的最大容量    -Xmn10M 堆中年轻(新生)代的大小
 * -XX:+UseSerialGC 指定垃圾收集器SerialGC(串型垃圾回收器)   -XX:+PrintGCDetails 打印内存中GC的行为     -verbose:gc 显示GC的情况
 * -XX:ServivorRatio=8    设置 New Generation新生代中的 Eden区与Servivor区比例是8:1
 */
public class gc_gcutil {
    //前提:配置一下vm的参数[JVM 配置]
    //GC(Allocation Failure)[DefNew: 7072k->(956k),0.0042301 secs...][Times:user=0.01 sys=0.00, real=0.01secs]...
    public static void main(String[] args) throws IOException {
        final int _1MB = 1024 * 1024;
        byte[] b1 = new byte[2 * _1MB];
        System.out.println("1...");
        System.in.read();//阻塞程序,当控制台输入回车键后继续执行
        byte[] b2 = new byte[2 * _1MB];
        System.out.println("2...");
        System.in.read();
        byte[] b3 = new byte[2 * _1MB];
        System.out.println("3...");
        System.in.read();
        byte[] a4= new byte[4*_1MB];
    }
}
/**
-gcutil 选项: 垃圾收集统计信息
    S0:幸存者空间0利用率占该空间当前容量的百分比
    S1:幸存者空间1利用率占空间当前容量的百分比
    E:Eden空间利用率占空间当前容量的百分比
    O:老年代利用率占空间当前容量的百分比
    M:元空间利用率占空间当前容量的百分比
    CCS:压缩的类空间利用率,以百分比表示
    YGC:新生代GC事件的数量
    YGCT:新生代垃圾回收时间
    FGC:完整GC事件的数量
    FGCT:完整的垃圾收集时间
    GCT:总垃圾收集时间
*/


3、jstack (Stack Trace forJava)  

查看或导出 Java 应用程序中线程堆栈信息,可以判断cpu占用率过高、死循环、死锁的情况

❀ 命令:jstack -l 进程ID

 

1)cpu占用率过高:

         1.使用Process Explorer工具,找到CPU占用率高的进程的id

     2.右击该进程,查看属性,在thread选项卡中,找到cpu占用率高的线程id

     3.把线程id转换成16进制

     4.使用jstack -l 查看进程的线程快照

     5.在线程快照中找到指定的线程,并分析代码

----通过工具,知道那个线程占用率高,然后在eclipse或者idea找到该占用率高的线程,从而知道占用率高的代码位置。

 

图1:使用Process Explorer工具,找到CPU占用率高的进程的id;右击该进程,查看属性,在thread选项卡中,找到cpu占用率高的线程id


image.png


图2:把线程id转换成16进制


51.png


 图3:使用jstack -l 查看进程的线程快照;在线程快照中找到指定的线程,并分析代码


52.png


案例(代码):


package jstack;
import java.io.IOException;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
 * jstack应用
 * @author Huangyujun
 *
 */
public class jstackTest {
    public static void main(String[] args) {
        System.out.println("start");
//        test1();
//        test2();
        test3();
        System.out.println("end");
    }
    //死循环
    public static void test1() {
        while(true) {}
    } 
    //等待控制台输入
    public static void test2() {
        try {
            System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        }
    } 
    //死锁【我醒来了,我的锁被你拿了,你睡了;你醒来了,你的锁被我拿了,我睡了-------我等你,你等我【等不到的人】】
    public static void test3() {
        Lock lock1 = new ReentrantLock();
        Lock lock2 = new ReentrantLock();
        new Thread(() -> {
            try {
                lock1.lock();
                Thread.sleep(100);
                lock2.lock();//需要加锁,但是加锁失败,锁被另外一个线程myThread2持有
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "myThread1").start();
        new Thread(() -> {
            try {
                lock2.lock();
                Thread.sleep(100);
                lock1.lock();//通过lock1加锁,失败,等待锁的释放,按照提示说是被myThread1持有,观察发现:myThread1中:lock1.lock(); Thread.sleep(100);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "myThread2").start();
    } 
}


//死循环

53.png

//等待控制台输入


54.png


//死锁


image.png


常识或需要储备知识~

1、System.in.read(); //让程序阻塞

2、Terminal 终端(方便,推荐) 也可以用win10的cmd控制台【dos窗口】

3、控制台输入gc日志的前提:配置一下jvm的参数[JVM 配置]

4、dos命令和进程命令相关的:

■ 常识----dos命令:

DOS命令,是操作系统的命令,是一种面向磁盘的操作命令,主要包括 目录操作类命令、磁盘操作类命令、文件操作类命令和其它命令。

✿ 常用操作----进程ID的查看与消灭进程:

1,cmd查看所有进程:netstat -ano

2,查看特定端口号的进程[例如:8080]:netstat -ano|findstr 8080

3,杀死对应的PID号对应的线程:taskkill /f /pid PID号

 

 

 

 

目录
相关文章
|
8月前
|
JavaScript Java Docker
干货含源码!如何用Java后端操作Docker(命令行篇)
只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
监控 前端开发 Java
Java SpringBoot –性能分析与调优
Java SpringBoot –性能分析与调优
|
缓存 监控 Linux
Linux性能分析利器:全面掌握perf工具
【10月更文挑战第18天】 在Linux系统中,性能分析是确保软件运行效率的关键步骤。`perf`工具,作为Linux内核自带的性能分析工具,为开发者提供了强大的性能监控和分析能力。本文将全面介绍`perf`工具的使用,帮助你成为性能优化的高手。
746 1
|
缓存 监控 Linux
掌握Linux性能分析:深入探索perf工具
【10月更文挑战第26天】
575 1
|
SQL 缓存 关系型数据库
MySQL高级篇——性能分析工具
MySQL的慢查询日志,用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long-query_time值的SQL,则会被记录到慢查询日志中。long_query_time的默认值为 10,意思是运行10秒以上(不含10秒)的语句,认为是超出了我们的最大忍耐时间值。它的主要作用是,帮助我们发现那些执行时间特别长的 SOL 查询,并且有针对性地进行优化,从而提高系统的整体效率。当我们的数据库服务器发生阻塞、运行变慢的时候,检查一下慢查询日志,找到那些慢查询,对解决问题很有帮助。
MySQL高级篇——性能分析工具
|
小程序 JavaScript Java
【Java】服务CPU占用率100%,教你用jstack排查定位
本文详细讲解如何使用jstack排查定位CPU高占用问题。首先介绍jstack的基本概念:它是诊断Java应用程序线程问题的工具,能生成线程堆栈快照,帮助找出程序中的瓶颈。接着,文章通过具体步骤演示如何使用`top`命令找到高CPU占用的Java进程及线程,再结合`jstack`命令获取堆栈信息并进行分析,最终定位问题代码。
1523 2
【Java】服务CPU占用率100%,教你用jstack排查定位
|
Web App开发 监控 JavaScript
一些常用的 Vue 性能分析工具
【10月更文挑战第2天】
756 1
|
运维 监控 Java
使用jps命令查看Java进程
`jps`是Java开发者和系统管理员的得力助手,它简化了Java进程监控的过程,使得快速检查应用运行状态变得轻而易举。通过合理利用其提供的参数,可以高效地进行故障排查、性能监控及日常管理任务,确保Java应用稳定运行。
935 2
|
监控 IDE Java
【Java性能调优新工具】JDK 22性能分析器:深度剖析,优化无死角!
【9月更文挑战第9天】JDK 22中的性能分析器为Java应用的性能调优提供了强大的支持。通过深度集成、全面监控、精细化分析和灵活报告生成等核心优势,性能分析器帮助开发者实现了对应用性能的全面掌控和深度优化。在未来的Java开发过程中,我们期待性能分析器能够继续发挥重要作用,为Java应用的性能提升贡献更多力量。
|
存储 虚拟化
使用DiskGenius工具来实现物理机迁移虚拟机,实现虚拟化
【9月更文挑战第1天】使用 DiskGenius 工具可将物理机迁移到虚拟机,实现系统与数据的虚拟化。此过程包括:安装 DiskGenius 和准备虚拟化平台;备份物理机数据;使用 DiskGenius 备份磁盘;在虚拟化软件中创建新虚拟机并导入磁盘备份;配置及调整虚拟机设置;测试性能并优化资源分配。这有助于测试、开发及系统管理。
1581 5