JDK的命令行工具

China☆狼群 提交于 2020-01-20 02:10:09

目录

一、jps:虚拟机进程状况工具

二、jstat:虚拟机统计信息监视工具

三、jinfo:java配置信息工具

四、jmap:java内存映像工具

五、jhat:虚拟机堆转储快照分析工具——仅做了解即可

六、jstack:java堆栈跟踪工具

使用jstack查看线程死锁——模拟


一、jps:虚拟机进程状况工具

linux自带查看进程命令:

  • ps -ef | grep java  查看运行的java进程

jps是jdk提供的一个查看当前java进程的小工具。查找当前用户的Java进程,而不是当前系统中的所有进程。

参数如下

  • jps -l 输出主类或jar的完全路径

  • jps -v 输出jvm 的参数

  • jps -m 输出main方法的参数
  • jps -q 只显示进程id。不显示类名

二、jstat:虚拟机统计信息监视工具

jstat是用于监视虚拟机各种运行状态信息的命令行工具。

  • jstat -gc 2764 250 20

上述命令的解释是,没250毫秒查询一次进程2764的垃圾收集状况,一共查询20次,省略后边两个参数,说明只查询一次,通常和jps命令结合使用。

相关监视选项含义:

  • S0C:第一个幸存区的大小
  • S1C:第二个幸存区的大小
  • S0U:第一个幸存区的使用大小
  • S1U:第二个幸存区的使用大小
  • EC:伊甸园区的大小
  • EU:伊甸园区的使用大小
  • OC:老年代大小
  • OU:老年代使用大小
  • MC:方法区大小
  • MU:方法区使用大小
  • CCSC:压缩类空间大小
  • CCSU:压缩类空间使用大小
  • YGC:年轻代垃圾回收次数
  • YGCT:年轻代垃圾回收消耗时间
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间

三、jinfo:java配置信息工具

jinfo 是 JDK 自带的命令,可以用来查看正在运行的 java 应用程序的扩展参数,包括Java System属性和JVM命令行参数;也可以动态的修改正在运行的 JVM 一些参数。当系统崩溃时,jinfo可以从core文件里面知道崩溃的Java应用程序的配置信息。

jinfo的用法:

  • jinfo pid :输出当前 jvm 进程的全部参数和系统属性

四、jmap:java内存映像工具

jmap命令可以获得运行中的jvm的堆的快照,从而可以离线分析堆,以检查内存泄漏,检查一些严重影响性能的大对象的创建,检查系统中什么对象最多,各种对象所占内存的大小等等。可以使用jmap生成Heap Dump。 

JVM Memory Map命令用于生成heap dump文件,如果不使用这个命令,还可以使用-XX:+HeapDumpOnOutOfMemoryError参数来让虚拟机出现OOM的时候自动生成dump文件。 jmap不仅能生成dump文件,还可以查询finalize执行队列、Java堆和永久代的详细信息,如当前使用率、当前使用的是哪种收集器等。

  • jmap -heap pid :查看相应进程堆信息情况,如使用哪种回收器,参数配置,分代状况等。

  • jmap -histo 9740 | more : 查看堆中对象统计信息,包括类、实例数量,合计容量等。

上示命令中,more是管道符下的分页命令,进行分页查看

  • jmap -dump:format=b,file=C:\Users\swadi\Desktop\dump.bin 9740 :生成堆转储快储快照到桌面

C:\Users\swadi\Desktop\ :本机桌面地址

dump.bin:文件名称

9740 :进程pid

五、jhat:虚拟机堆转储快照分析工具——仅做了解即可

Java Virtual Machine Heap Analysis Tool 虚拟机堆转储快照分析工具,用于分析heapdump文件,它会建立一个HTTP/HTML服务器,让用户可以在浏览器上查看分析结果。

不过,在实际工作中,除非真的没有别的工具可用,否则一般不会去直接使用jhat命令来分析demp文件,主要原因有二:一是一般不会在部署应用程序的服务器上直接分析dump文件,即使可以这样做,也会尽量将dump文件拷贝到其他机器上进行分析,因为分析工作是一个耗时且消耗硬件资源的过程,既然都要在其他机器上进行,就没必要受到命令行工具的限制了;另外一个原因是jhat的分析功能相对来说很简陋,VisualVM以及专门分析dump文件的Eclipse Memory Analyzer、IBM HeapAnalyzer等工具,都能实现比jhat更强大更专业的分析功能。

测试用例:执行下列程序

public class OOMErrorTest {
    public static void main(String[] args) {
        String str = "classOOM";
        for(int i = 0;i<999999999;i++){
            str += str;
            System.out.println(str);
        }
    }
}

给定虚拟机运行参数:

-Xmx10m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:\Users\swadi\Desktop\

运行结果:

执行完后,程序堆内存溢出,此时在桌面生成了一个内存分析文件,使用jhat命令,可生成一个链接地址,如图:

使用链接地址,可查看内存溢出的相关信息:

六、jstack:java堆栈跟踪工具

jstack是jdk自带的线程堆栈分析工具,使用该命令可以查看或导出 java 应用程序中线程堆栈信息

jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。 线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。 如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态,jstack是非常有用的。

  • jstack -l pid 查看线程堆栈信息

使用jstack查看线程死锁——模拟

在springboot启动类中模仿一个线程死锁,开启springboot工程,代码如下:

@SpringBootApplication
@EnableScheduling // 开启定时任务
public class MyApplication {
    public static void main(String[] args) {
        Logger logger = LoggerFactory.getLogger(MyApplication.class);
        try {
            SpringApplication.run(MyApplication.class);
            logger.info("springBoot启动成功...");
        } catch (Exception e) {
            logger.info("SpringBoot启动失败...");
        }
    }

    public static Object lock1 = new Object();
    public static Object lock2 = new Object();

    /**
     * 在springboot项目启动的时候所执行的方法
     * 在bean加载完但用户线程进来之前执行的方法
     */
    @PostConstruct
    public void deadLock(){
        new Thread(()->{
            synchronized (lock1){
                try {
                    System.out.println(Thread.currentThread().getName()+":get lock1");
                    Thread.sleep(3000L);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                synchronized (lock2){
                    System.out.println(Thread.currentThread().getName()+":get lock2");
                }
            }
        },"Thread1").start();
        new Thread(()->{
            synchronized (lock2){
                try {
                    System.out.println(Thread.currentThread().getName()+":get lock2");
                    Thread.sleep(3000L);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                synchronized (lock1){
                    System.out.println(Thread.currentThread().getName()+":get lock1");
                }
            }
        },"Thread2").start();
    }
}

执行完后,通过jstack命令查看线程状态:

往下翻,在线程堆栈信息中,我们可以看到打印的死锁信息,如图:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!