JVM调优(7)问题定位和信息打印

1.找到对应进程的pid

 ps -ef | grep tomcat
 #或者使用jps
 jps -lvm #查看当前机器上运行的Java进程

jps命令格式如下:
命令格式 jps [options] [hostid]
注:如果不指定hostid就默认为当前主机或服务器。
命令行参数选项说明如下:
-q 不输出类名、Jar名和传入main方法的参数
-m 输出传入main方法的参数
-l 输出main类或Jar的全限名
-v 输出传入JVM的参数

结果类似如下格式:

    root      22216      1 99 11:34 pts/17   07:49:56 /usr/bin/java -Djava.util.logging.config.file=/search/odin/xx/tomcat7/conf/logging.properties -Djava.util.logging
[allenlee@localhost ~ jps
22213 RemoteMavenServer
22214 Launcher
22215 
22216 ArkManagerApplication
22217 Jps

找到出问题的进程pid, 如上为22216,

2.根据pid打印详细信息

pidstat 方式

pidstat -p 22216 1 100 -u -t
(-p指定进行pid,-u表示对CPU使用率的监控, -t参数将系统性能的监控细化到线程级别)
输出结果如下:

    162122TGID       TID    %usr %system  %guest    %CPU   CPU  Command
    16212291233         -  916.00   27.00    0.00  943.00    21  java
    162122-     91233    0.00    0.00    0.00    0.00    21  |__java
    162122-     91234    0.00    0.00    0.00    0.00     2  |__java
    162122-     91235   84.00    2.00    0.00   86.00    24  |__java

其中最后一行,%usr,%CPU的占有率很高,说明这些线程占了大部分CPU的时间,

jstat 方式

jstat(JVM statistics Monitoring)是用于监视虚拟机运行时状态信息的命令,它可以显示出虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。

命令格式

jstat [option] PID [interval] [count]

参数

[option] : 操作参数
LVMID : 本地虚拟机进程ID
[interval] : 连续输出的时间间隔
[count] : 连续输出的次数

option 详解

-class

监视类装载、卸载数量、总空间以及耗费的时间

jstat -class 22216

结果

    Loaded Bytes Unloaded Bytes Time 
    9293 17927.5 0 0.0 33.90 

Loaded : 加载class的数量
Bytes : class字节大小
Unloaded : 未加载class的数量
Bytes : 未加载class的字节大小
Time : 加载时间

-compiler

输出JIT编译过的方法数量耗时等

jstat -compiler 22216

结果

    Compiled Failed Invalid Time FailedType FailedMethod 
    10869 1 0 24.52 1 org/aspectj/weaver/Iterators$6 hasNext 

Compiled : 编译数量
Failed : 编译失败数量
Invalid : 无效数量
Time : 编译耗时
FailedType : 失败类型
FailedMethod : 失败方法的全限定名

-gc

垃圾回收堆的行为统计,常用命令

jstat -gc 22216

结果

    S0C    S1C    S0U  S1U     EC       EU      OC       OU       MC       MU    CCSC   CCSU  YGC YGCT FGC FGCT GCT 
  86016.0 89600.0 0.0 8769.9 148992.0 26212.9 332288.0 247371.9 59008.0 57361.6 6784.0 6348.8 17 0.379   3  0.345 0.724 

C即Capacity 总容量,U即Used 已使用的容量
S0C : survivor0区的总容量
S1C : survivor1区的总容量
S0U : survivor0区已使用的容量
S1C : survivor1区已使用的容量
EC : Eden区的总容量
EU : Eden区已使用的容量
OC : Old区的总容量
OU : Old区已使用的容量
MC:方法区大小
MU:方法区使用大小
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
YGC : 新生代垃圾回收次数
YGCT : 新生代垃圾回收时间
FGC : 老年代垃圾回收次数
FGCT : 老年代垃圾回收时间
GCT : 垃圾回收总消耗时间

jstat -gc 22216 2000 20

这个命令意思就是每隔2000ms输出1262的gc情况,一共输出20次

-gccapacity

同-gc,不过还会输出Java堆各区域使用到的最大、最小空间

jstat -gccapacity 42712

结果

    NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC 
    20992.0 338432.0 337920.0 86016.0 89600.0 148992.0 42496.0 677376.0 332288.0 332288.0 0.0 1101824.0 59008.0 0.0 1048576.0 6784.0 17 3 

NGCMN:新生代最小容量
NGCMX:新生代最大容量
NGC:当前新生代容量
S0C:第一个幸存区大小
S1C:第二个幸存区的大小
EC:伊甸园区的大小
OGCMN:老年代最小容量
OGCMX:老年代最大容量
OGC:当前老年代大小
OC:当前老年代大小
MCMN:最小元数据容量
MCMX:最大元数据容量
MC:当前元数据空间大小
CCSMN:最小压缩类空间大小
CCSMX:最大压缩类空间大小
CCSC:当前压缩类空间大小
YGC:年轻代gc次数
FGC:老年代GC次数

-gcutil

同-gc,不过输出的是已使用空间占总空间的百分比

jstat -gcutil 22216

结果

    S0     S1  E     O     M     CCS  YGC  YGCT FGC FGCT   GCT 
    0.00 9.79 21.39 74.45 97.21 93.59 17  0.379  3  0.345 0.724

S0:幸存1区当前使用比例
S1:幸存2区当前使用比例
E:伊甸园区使用比例
O:老年代使用比例
M:元数据区使用比例
CCS:压缩使用比例
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间

-gccause

垃圾收集统计概述(同-gcutil),附加最近两次垃圾回收事件的原因

jstat -gccause 22216

结果

    S0 S1 E O M CCS YGC YGCT FGC FGCT GCT LGCC GCC 
    0.00 9.79 21.39 74.45 97.21 93.59 17 0.379 3 0.345 0.724 Allocation Failure No GC

LGCC:最近垃圾回收的原因
GCC:当前垃圾回收的原因

-gcnew 统计新生代的行为
jstat -gcnew 22216

结果

    S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT 
    86016.0 89600.0 0.0 8769.9 4 15 86016.0 148992.0 34327.2 17 0.379

S0C:第一个幸存区大小
S1C:第二个幸存区的大小
S0U:第一个幸存区的使用大小
S1U:第二个幸存区的使用大小
TT:对象在新生代存活的次数
MTT:对象在新生代存活的最大次数
DSS:期望的幸存区大小
EC:伊甸园区的大小
EU:伊甸园区的使用大小
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间

-gcnewcapacity 新生代与其相应的内存空间的统计
jstat -gcnewcapacity 22216

结果

    NGCMN   NGCMX      NGC    S0CMX    S0C     S1CMX     S1C     ECMX      EC     YGC FGC 
    20992.0 338432.0 337920.0 112640.0 86016.0 112640.0 89600.0 337408.0 148992.0 17   3

NGCMN:新生代最小容量
NGCMX:新生代最大容量
NGC:当前新生代容量
S0CMX:最大幸存1区大小
S0C:当前幸存1区大小
S1CMX:最大幸存2区大小
S1C:当前幸存2区大小
ECMX:最大伊甸园区大小
EC:当前伊甸园区大小
YGC:年轻代垃圾回收次数
FGC:老年代回收次数

-gcold 老年代垃圾回收统计
jstat -gcold 22216

结果

    MC MU CCSC CCSU OC OU YGC FGC FGCT GCT 
    59008.0 57361.6 6784.0 6348.8 332288.0 247371.9 17 3 0.345 0.724

MC:方法区大小
MU:方法区使用大小
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
OC:老年代大小
OU:老年代使用大小
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间

-gcoldcapacity 老年代内存统计
jstat -gcoldcapacity 22216

结果

    OGCMN    OGCMX    OGC       OC     YGC FGC FGCT   GCT 
    42496.0 677376.0 332288.0 332288.0 17   3  0.345 0.724

OGCMN:老年代最小容量
OGCMX:老年代最大容量
OGC:当前老年代大小
OC:老年代大小
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间

-gcmetacapacity 元数据空间统计
jstat -gcmetacapacity 22216

结果

    MCMN   MCMX     MC   CCSMN   CCSMX    CCSC  YGC FGC  FGCT GCT 
    0.0 1101824.0 59008.0 0.0  1048576.0 6784.0 17   3  0.345 0.724

MCMN:最小元数据容量
MCMX:最大元数据容量
MC:当前元数据空间大小
CCSMN:最小压缩类空间大小
CCSMX:最大压缩类空间大小
CCSC:当前压缩类空间大小
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间

-printcompilation

hotspot编译方法统计(JVM编译方法统计)

jstat -printcompilation 22216

结果

    Compiled Size Type Method 
    10954 307 1 java/util/Formatter$FormatSpecifier printString

Compiled:被执行的编译任务的数量
Size:方法字节码的字节数
Type:编译类型
Method:编译方法的类名和方法名。类名使用”/” 代替 “.” 作为空间分隔符. 方法名是给出类的方法名. 格式是一致于HotSpot - XX:+PrintComplation 选项

jmap 方式

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

命令格式

jmap [option] PID

参数

dump : 生成堆转储快照
finalizerinfo : 显示在F-Queue队列等待Finalizer线程执行finalizer方法的对象
heap : 显示Java堆详细信息
histo : 显示堆中对象的统计信息
permstat : to print permanent generation statistics
F : 当-dump没有响应时,强制生成dump快照

参数详细讲解

-dump

堆到文件,format指定输出格式,live指明是活着的对象,file指定文件名

    [localhost:~ root# jmap -dump:live,format=b,file=/Users/allenlee/Downloads/dump.hprof 22216
    Dumping heap to /data/dump.hprof ... 
    Heap dump file created
jmap -heap 22216
[localhost:~ root# jmap -heap 22216
Attaching to process ID 22216, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.102-b14
using thread-local object allocation.
Parallel GC with 2 thread(s) 
-histo

打印堆的对象统计,包括对象数、内存大小等等 (因为在dump:live前会进行full gc,如果带上live则只统计活对象,因此不加live的堆大小要大于加live堆的大小 )

对象类型,说明如下:
B byte
C char
D double
F float
I int
J long
Z boolean
[ 数组,如[I表示int[]
[L+类名 其他对象

jmap -histo:live 22216 | more 

结果

    map -histo:live 22216 | more

 num     #instances         #bytes  class name
----------------------------------------------
   1:         95106       12788424  [C
   2:         26994        2375472  java.lang.reflect.Method
   3:         93686        2248464  java.lang.String
   4:         49734        1591488  java.util.concurrent.ConcurrentHashMap$Node
   5:         10848        1214672  java.lang.Class
   6:         20047        1149440  [Ljava.lang.Object;
   7:          4997         864904  [B
   8:         19670         786800  java.util.LinkedHashMap$Entry
   9:          4602         624336  [I
  10:          8338         611392  [Ljava.util.HashMap$Node;
  11:         18065         578080  java.util.HashMap$Node
  12:         17029         544928  java.lang.ref.WeakReference
  13:          9501         532056  java.util.LinkedHashMap
  14:           198         439920  [Ljava.util.concurrent.ConcurrentHashMap$Node;
  15:         17741         392384  [Ljava.lang.Class;
  16:         16093         386232  org.springframework.core.MethodClassKey
  17:         15814         379536  java.util.ArrayList
  18:          8323         332920  java.lang.ref.SoftReference
  19:          7654         306160  com.sun.org.apache.xerces.internal.dom.DeferredTextImpl
  20:         17214         275424  java.lang.Object
  21:          6554         254896  [Ljava.lang.String;

jhat 方式

jhat(JVM Heap Analysis Tool)命令是与jmap搭配使用,用来分析jmap生成的dump,jhat内置了一个微型的HTTP/HTML服务器,生成dump的分析结果后,可以在浏览器中查看。在此要注意,一般不会直接在服务器上进行分析,因为jhat是一个耗时并且耗费硬件资源的过程,一般把服务器生成的dump文件复制到本地或其他机器上进行分析

分析同样一个dump快照,MAT需要的额外内存比jhat要小的多的多,所以建议使用MAT来进行分析,当然也看个人偏好。

allenlee@localhost  ~ jhat -J-Xmx512m /Users/allenlee/Downloads/dump.hprof
  eading from dump.hprof...
  Dump file created Tue Dec 11 11:13:42 CST 2018
  Snapshot read, resolving...
  Resolving 271678 objects...
  Chasing references, expect 54 dots......................................................
  Eliminating duplicate references......................................................
  Snapshot resolved.
  Started HTTP server on port 7000
  Server is ready.

在浏览器打开Http://localhost:7000进行快照分析
在这里插入图片描述

点进去每个类
在这里插入图片描述
堆快照分析主要在最后面的Heap Histogram里,里面根据class列出了dump的时候所有存活对象。

jstack 方式

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

命令格式

jstack [option] PID

option参数

-F : 当正常输出请求不被响应时,强制输出线程堆栈
-l : 除堆栈外,显示关于锁的附加信息
-m : 如果调用到本地方法的话,可以显示C/C++的堆栈

jstack -l 62776|more

将信息拷贝到文件中
jstack -l 62776 > /usr/local/tmp/info.txt

该文件中会出现类似如下内容

"Thread-0" prio=10 tid=0xb75b300 nid=0x4b4 runnable [0x8f171000]
java.lang.Thread.State: runnable
at javatunning.ch6.toolscheck.HoldCPUMain$<strong>HoldCPUTask</strong>.run(HoldCPUMain.java:7)

资料

https://blog.csdn.net/shendeguang/article/details/79041717
https://www.cnblogs.com/ityouknow/p/5714703.htm
http://blog.csdn.net/maosijunzi/article/details/46049117

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值