zoukankan      html  css  js  c++  java
  • 必知必会的JavaJDK工具

    JDK中有很多用于监控诊断的系统工具,对于Java程序员来说,无疑是用来了解自己程序运行时性能好坏的强大工具。

    在JDK的bin目录下就可以找到这些工具。

    1

    JPS

    在Linux有一个命令叫做ps,可以查看系统当前所有的进程,而JDK提供的jps也是类似,查看正在运行的Java进程。

    可以看到该命令的参数。

    2

    在默认情况下,jps的输出信息包括Java进程的进程ID以及主类名。

    我们还可以通过追加参数,来打印额外的信息。

    例如,-l将打印模块名以及包名;

    3

    -v将打印传递给 Java 虚拟机的参数(如-XX:+UnlockExperimentalVMOptions -XX:+UseZGC);

    4

    -m将打印传递给主类的参数。

    5

    也可以使用-lvm一同使用。

    在JVM启动时,会创建一个perf memory来存放PerfData,如果使用了参数-XX:-UsePerfData,禁止其它进程可见,那么jps命令就无法查看到该Java进程了。

    Jstat

    Jstat命令是用于打印某个Java进程的运行数据。

    6

    它支持使用-class查看类加载相关的数据,-compiler-printcompilation查看即时编译相关的信息。

    以及-gc等垃圾回收相关的数据。

    执行时需要指定子命令和Java进程ID。

    7

    上图中,S0C和S1C代表了两个Survivor区的大小,C是指Capacity,容量。

    S0U和S1U是指两个Survivor区已使用的大小,U是指Utility,实用。

    EC和EU代表了Eden区的容量及使用。

    OC和OU代表了Old区的容量及使用。

    MC和MU代表了方法区的容量及使用。

    CCSC和CCSU代表了压缩类空间的容量和使用大小 ,这个相对来说很少使用。

    YGC代表了YoungGC,也就是年轻代GC发生的次数,更准确应该叫做MinorGC,YGCT代表所用的时间。

    FGC代表FullGC发生的次数,它发生在老年代,FGCT代表所用的时间。

    GCT代表所有GC所占用的时间。

    可以看到11次YGC只耗时0.439,而8次FGC却用了数倍时间,1.419。

    现在我们已经知道每一个标记代表什么了,可以尝试一下使用更详细的gc子命令来查看对应Java进程了。

    jstat命令默认执行一次只返回一次,如果我想一直监控某个Java进程,可以添加可以时间参数。

    如下图,jstat -gcnew 13496 500,后面跟一个500,就说明每500ms打印一次。

    8

    还可以指定打印的次数,比如jstat -gcnew 13496 500 5,后面跟500 5,就说明每500ms打印一次,总共打印5次。

    9

    在我们查看内存区域容量变化时,如果发现老年代的使用率不断增加,就说明有大量对象无法进行回收,我们的程序出现了性能上的问题。

    再比如,我们可以添加-t来打印程序运行时间Timestamp,如果GCT占据了大部分程序运行时间,或者说这个时间比在持续上升时。就说明我们程序的堆内存已经在逐步走向奔溃了。

    10

    Jmap

    知道程序有了问题,我们就可以利用Jmap命令来分析了。

    Jmap同样包括多条子命令。

    11

    -clstats,该子命令将打印被加载类的信息。

    13

    -finalizerinfo,该子命令将打印所有待 finalize 的对象。

    14

    -histo,该子命令将统计各个类的实例数目以及占用内存,并按照内存使用量从多至少的顺序排列。此外,-histo:live只统计堆中的存活对象。

    12

    -dump,该子命令将导出 Java 虚拟机堆的快照。同样,-dump:live只保存堆中的存活对象。

    我们通常会利用jmap -dump:live,format=b,file=filename.bin命令,将堆中所有存活对象导出至一个文件之中。

    15

    -heap,该子命令将输出当前堆中的配置信息。

    16

    Jinfo

    Jinfo命令可用来查看目标Java进程的参数。

    17

    Jstack

    这是一个非常有用的命令,它可以用来打印目标 Java 进程中各个线程的栈轨迹,以及这些线程所持有的锁,所以这个命令可以帮助我们处理死锁。

    我们来写一个简单的会产生死锁的代码。

    18

    程序跑着跑着就会发生死锁。

    19

    我们使用jstack来查看。

    20

    可以看到线程Thread-a,它locked了String.class这个锁,在waiting等待Main.class

    而线程Thread-b,它locked了Main.class,在waiting等待String.class

    Jstack甚至帮我们找到了死锁发生的原因。

    21

  • 相关阅读:
    背水一战 Windows 10 (26)
    背水一战 Windows 10 (25)
    背水一战 Windows 10 (24)
    背水一战 Windows 10 (23)
    背水一战 Windows 10 (22)
    背水一战 Windows 10 (21)
    背水一战 Windows 10 (20)
    背水一战 Windows 10 (19)
    背水一战 Windows 10 (18)
    背水一战 Windows 10 (17)
  • 原文地址:https://www.cnblogs.com/LexMoon/p/jdktools.html
Copyright © 2011-2022 走看看