JVM之监控工具(六)

释放双眼,带上耳机,听听看~!

JPS

JPS全称为(Java Virtual Machine Process Status Tool),JPS主要用来输出JVM运行的进程状态信息,JPS就像是linux中的PS命令,只不过它只PS Java进程。

语法如下:

jps [-q] [-mlvV] [<hostid>]
    -q:静默模式,不输出java程序的类名称、Jar包名称和传入的main方法参数,只输出java的pid
    -v:输出我们传递给JVM的所有参数
    -m:输出传入main方法的参数
    -l:输出main类或jar包的全名(对于不是通过jar包运行的程序只显示main类名称)
    -V:显示通过flag文件传递给JVM的参数
    [<hostid>]:主机id,默认为localhost

JINFO

jinfo主要输出给定Java进程的所有配置信息

语法如下:

jinfo [option] <pid>                                            #连接到正在运行的进程
    -flags:打印VM标志
    -sysprops:打印Java系统属性
    -flag <name>:打印指定VM标志的值

实例演示:

jinfo -flags 20827                                              #打印VM标志,指定java进程的pid
jinfo -flag ConcGCThreads 20827                                 #打印指定的VM标志的值
jinfo -sysprops 20827                                           #打印Java系统属性信息,指定java进程的pid

JSTACK

jstack主要用来查看指定Java进程中线程栈的相关信息。

语法如下:

jstack [-l] <pid>
jstack -F [-m] [-l] <pid>
    -l:long listing,打印关于锁的附加信息,因此,发生死锁时常用此选项;
    -m:混合模式,即输出java堆栈信息,又输出C/C++堆栈信息
    -F:当使用 "jstack -l PID" 无响应时,可以使用 -F 进行强制输出信息

实例如下:

jstack -m 20827                 #输出pid为20827 java进程的堆栈信息
jstack -l 20827                 #输出pid为20827 java进程关于锁信息
jstack -F -m -l 20827           #强制输出pid为 20827 java进程的堆栈信息以及锁信息

jstack可以定位到线程堆栈,根据线程堆栈信息我们可以定位到具体代码,所以它在JVM性能调优中用的非常多。
下面我们来一个实例找出某个Java进程中最耗费CPU的Java线程并定位堆栈信息。

第一步:

定位Java进程的PID
[root@tweb02 ~]# ps -ef|grep crmnew | grep -v grep | awk '{print $2}'
20827

第二步:

找出该进程内最耗费CPU的线程
top -cHp 20827      

下图中pid列为java pid 20827进程中的线程pid
下图中TIME+列为各个Java线程耗费CPU的时间,耗时最长的pid线程号为20860

第三步:
用printf命令来将此线程号转换为16进制

[root@tweb02 ~]# printf "%x\n" 20860
517c  

第四步:
使用jstack工具来输出Java进程的堆栈信息,然后过滤出上面找到的线程信息

[root@tweb02 ~]# jstack 20827 | grep 517c
"apm-reporter" #12 daemon prio=5 os_prio=0 tid=0x00007feba8a6a800 nid=0x517c runnable [0x00007feb3ccf9000]

"apm-reporter"是个类,可以看到CPU消耗在此类的runnable上面,然后根据此类去找分析代码原因

JSTAT

jstat是一个jvm统计检测工具,输出指定的java进程统计信息。

语法如下:

jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
jstat -options              #获取支持选项
    -class:显示指定类的加载和卸载情况
    -compiler:显示JIT编译器编译情况
    -gc:显示GC垃圾回收操作相关情况
    -gccapacity:统计堆中各代的容量
    -gccause:
    -gcmetacapacity
    -gcnew:新生代
    -gcnewcapacity
    -gcold:旧生代
    -gcoldcapacity
    -gcutil
    -printcompilation
    
[<interval> <count>]
    interval:时间间隔,单位是毫秒
    count:显示的次数

实例如下:

[root@tweb02 ~]# jstat -class 20827
Loaded  Bytes  Unloaded  Bytes     Time
 21595 44677.5      284   424.5      42.12
 loaded:类加载数量
 bytes:类字节大小
 unloaded:类卸载情况
[root@tweb02 ~]# jstat -compiler 20827
Compiled Failed Invalid   Time   FailedType FailedMethod
   28927      2       0   256.67          1 org/springframework/cglib/core/MethodWrapper$MethodWrapperKey$KeyFactoryByCGLIB$552be97a hashCode
输出进程为20827的GC相关信息
[root@tweb02 ~]# jstat -gc 20827
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
 0.0   20480.0  0.0   20480.0 530432.0 161792.0 1546240.0   416362.0  166832.0 152552.4 16844.0 14708.8     71    3.354   0      0.000    3.354
 
根据时间输出 ,连续输出10次,每次输出间隔500ms
[root@tweb02 ~]# jstat -gc 20827 500 10
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
 0.0   20480.0  0.0   20480.0 530432.0 389120.0 1546240.0   416362.0  166832.0 152552.4 16844.0 14708.8     71    3.354   0      0.000    3.354
 0.0   20480.0  0.0   20480.0 530432.0 389120.0 1546240.0   416362.0  166832.0 152552.4 16844.0 14708.8     71    3.354   0      0.000    3.354
 0.0   20480.0  0.0   20480.0 530432.0 389120.0 1546240.0   416362.0  166832.0 152552.4 16844.0 14708.8     71    3.354   0      0.000    3.354
 0.0   20480.0  0.0   20480.0 530432.0 389120.0 1546240.0   416362.0  166832.0 152552.4 16844.0 14708.8     71    3.354   0      0.000    3.354
 0.0   20480.0  0.0   20480.0 530432.0 389120.0 1546240.0   416362.0  166832.0 152552.4 16844.0 14708.8     71    3.354   0      0.000    3.354
 0.0   20480.0  0.0   20480.0 530432.0 390144.0 1546240.0   416362.0  166832.0 152552.4 16844.0 14708.8     71    3.354   0      0.000    3.354
 0.0   20480.0  0.0   20480.0 530432.0 390144.0 1546240.0   416362.0  166832.0 152552.4 16844.0 14708.8     71    3.354   0      0.000    3.354
 0.0   20480.0  0.0   20480.0 530432.0 390144.0 1546240.0   416362.0  166832.0 152552.4 16844.0 14708.8     71    3.354   0      0.000    3.354
 0.0   20480.0  0.0   20480.0 530432.0 390144.0 1546240.0   416362.0  166832.0 152552.4 16844.0 14708.8     71    3.354   0      0.000    3.354
 0.0   20480.0  0.0   20480.0 530432.0 390144.0 1546240.0   416362.0  166832.0 152552.4 16844.0 14708.8     71    3.354   0      0.000    3.354
 
输出详解:
S0C:堆内存中的新生代存活区From (Survivor 0)的容量
S01:堆内存中的新生代存活区To (Survivor 1)的容量
S0U:堆内存中的新生代存活区From (Survivor 0)的使用量(Used)
S1U: 堆内存中的新生代存活区To (Survivor 1)的使用量(Used)
EC:堆内存中新生代Eden伊甸园区的容量
EU:堆内存中新生代Eden伊甸园区的使用量
OC:堆内存中旧生代Old区的容量
OU:堆内存中旧生代Old区的使用量
MC:堆内存中Metaspace管理区的容量(原jdk1.7中永久代)
MU:堆内存中Metaspace管理区的使用量(原jdk1.7中永久代)
CCSC:堆内存中Compressed Class Space压缩类空间管理区容量(原jdk1.7中永久代)
CCSU:堆内存中Compressed Class Space压缩类空间管理区使用量(原jdk1.7中永久代)
YGC:堆内存中新生代的GC次数
YGCT:堆内存中新生代的GC耗时总和
FGC:堆内存中的Full GC次数
FGCT:堆内存中的Full GC耗时总和
GCT:堆内存中的所有GC总耗时总和

平衡点:
我们可以通过 jstat -gc 20827 500 1000,间隔500ms输出一次GC信息,共输出1000次来动态查看新生代GC和旧生代GC的频率,如果新生代GC频率较高则调整堆内存中的新生代大小,如果旧生代GC频率也很高,可以调整堆内存旧生代的大小,以此来优化GC频率。

JVM参数

可以通过向JVM配置文件添加参数来将GC操作记录到日志中,参数如下:

第一种方案:

-XX:+PrintGC                                    #输出GC的简要信息(简要信息与详细信息保留一个即可)
-XX:+PrintGCDetails                             #输出GC的详细信息(简要信息与详细信息保留一个即可)
-XX:+PrintGCDateStamps                          #输出GC的时间戳
-XX:+PrintTenuringDistribution                  #输出对象年龄
-XX:+PrintGCApplicationStoppedTime              #输出GC暂停时间
-Xloggc:logs/gc-%t.log                          #输出gc日志文件名跟时间戳 %t 的格式为 YYYY-MM-DD_HH-MM-SS(当程序重启则写入一个新的gc日志中)

第二种方案
不推荐此方案,详情参考:为什么不推荐启用UseGCLogFileRotation来记录GC日志?

-XX:+PrintGC                                    #输出GC的简要信息(简要信息与详细信息保留一个即可)
-XX:+PrintGCDetails                             #输出GC的详细信息(简要信息与详细信息保留一个即可)
-XX:+PrintGCDateStamps                          #输出GC的时间戳
-XX:+PrintTenuringDistribution                  #输出对象年龄
-XX:+PrintGCApplicationStoppedTime              #输出GC暂停时间
-Xloggc:logs/gc.log                             #输出gc日志文件到指定 logs/gc.log
-XX:+UseGCLogFileRotation                       #开启GC日志旋转
-XX:NumberOfGCLogFiles=32                       #GC日志最多存储32个日志文件,超过32个自动删除
-XX:GCLogFileSize=64m                           #每个GC日志文件最多64M,超过64M将写入下个GC日志

JCONSOLE

JConsole 是一个内置 Java 性能分析器,可以从命令行(直接输入jconsole)或在 GUI shell (jdk\bin下打开)中运行。
它用于对JVM中内存,线程和类等的监控。可使用JTop插件。它可以监控本地的jvm,也可以监控远程的jvm,也可以同时监控几个jvm。
这款工具的好处在于,占用系统资源少,而且结合Jstat,可以有效监控到java内存的变动情况,以及引起变动的原因。在项目追踪内存泄露问题时,很实用。

1.jconsole使用
windows下进入到jdk安装目录下的bin目录下,双击jconsole.exe

Mac下安装jdk后会自动设置环境变量,直接在终端中输入命令来启动,启动后可以监控本地进程和远程进程,这里以远程进程为例,输入远程地址的IP地址加JVM开放的端口,如果你设置了用户名和密码则一并输入。

2.JConsole查看当前程序/进程的全局情况

3.内存使用情况和GC回收情况

4.线程以及死锁情况

5.JAVA程序的VM标志及相关运行参数信息

6.Mbean

在进行对Java程序监控的时候,需要到这里来指定参数

JVisualVM

JVisualVM的用法跟Jconsole没很大区别,同样的启动方法,然后添加远程主机,远程主机添加后再添加JMX连接即可看到与Jconsole类似的信息。

人已赞赏
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
有新消息 消息中心
搜索