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

  • 相关阅读:
    iptables一次性封多个ip,使用ipset 工具
    计算机网络知识整理
    SpringBoot启动流程及其原理
    CAP与Base理论
    Java7与Java8中的HashMap和ConcurrentHashMap知识点总结
    用chrome浏览器进行前端debug和停止debug
    Java synchronized实现原理总结和偏量锁、轻量锁、重量锁、自旋锁
    WIN10笔记本屏幕亮度无法调节,一直是最高亮度
    Win10任务栏卡死解决方法
    ClassLoader类加载器 & Java类加载机制 & 破坏双亲委托机制
  • 原文地址:https://www.cnblogs.com/LexMoon/p/jdktools.html
Copyright © 2011-2022 走看看