JVM调优常用命令总结

JVM调优常用命令总结

**查询进程pid** 
		ps -ef | grep tomcat

jps命令

命令格式
options参数解释:
-l : 输出主类全名或jar路径
-q : 只输出LVMID
-m : 输出JVM启动时传递给main()的参数
-v : 输出JVM启动时显示指定的JVM参数

事例
jps -l pid

[root@localhost ~]# jps -l
32249 org.apache.catalina.startup.Bootstrap
1354 sun.tools.jps.Jps
5087 /opt/zbjk/kettle/data-integration/launcher/pentaho-application-launcher-7.1.0.0-12.jar

jps -m

[root@localhost ~]# jps -m
1428 Jps -m
32249 Bootstrap start
5087 pentaho-application-launcher-7.1.0.0-12.jar -lib ./../libswt/linux/x86_64/ 

jps -q

[root@localhost ~]# jps -q
1493
32249
5087

jps -v 输出jvm参数

[root@localhost ~]# jps -v
1640 Jps -Denv.class.path=.:/usr/java/jdk1.8.0_131/lib/dt.jar:/usr/java/jdk1.8.0_131/lib/tools.jar -Dapplication.home=/usr/java/jdk1.8.0_131 -Xms8m
32249 Bootstrap -Djava.util.logging.config.file=/opt/zbjk/tomcat_bis_01/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Xms1024m -Xmx1024m -Xss1024K -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=512m -Djdk.tls.ephemeralDHKeySize=2048 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=192.168.102.234 -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=9999 -Djava.endorsed.dirs=/opt/zbjk/tomcat_bis_01/endorsed -Dcatalina.base=/opt/zbjk/tomcat_bis_01 -Dcatalina.home=/opt/zbjk/tomcat_bis_01 -Djava.io.tmpdir=/opt/zbjk/tomcat_bis_01/temp
5087 pentaho-application-launcher-7.1.0.0-12.jar -Xms1024m -Xmx2048m -XX:MaxMetaspaceSize=512m -Dfile.encoding=UTF-8 -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2 -Djava.library.path=./../libswt/linux/x86_64/ -DKETTLE_HOME= -DKETTLE_REPOSITORY= -DKETTLE_USER= -DKETTLE_PASSWORD= -DKETTLE_PLUGIN_PACKAGES= -DKETTLE_LOG_SIZE_LIMIT= -DKETTLE_JNDI_ROOT=

jinfo命令

options参数解释:
-flag 打印指定名称的参数
-flag [+|-] 打开或关闭参数
-flag = 设置参数
-flags 打印所有参数
-sysprops 打印系统配置
打印上面两个选项

命令 jinfo -flags pid
查看 JVM 参数:

[root@localhost ~]# jinfo -flags 32249
Attaching to process ID 32249, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.131-b11
Non-default VM flags: -XX:CICompilerCount=3 -XX:InitialHeapSize=1073741824 -XX:+ManagementServer -XX:MaxHeapSize=1073741824 -XX:MaxMetaspaceSize=536870912 -XX:MaxNewSize=357564416 -XX:MetaspaceSize=536870912 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=357564416 -XX:OldSize=716177408 -XX:ThreadStackSize=1024 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC 
Command line:  -Djava.util.logging.config.file=/opt/zbjk/tomcat_bis_01/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Xms1024m -Xmx1024m -Xss1024K -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=512m -Djdk.tls.ephemeralDHKeySize=2048 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=192.168.102.234 -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=9999 -Djava.endorsed.dirs=/opt/zbjk/tomcat_bis_01/endorsed -Dcatalina.base=/opt/zbjk/tomcat_bis_01 -Dcatalina.home=/opt/zbjk/tomcat_bis_01 -Djava.io.tmpdir=/opt/zbjk/tomcat_bis_01/temp

查看系统参数

jinfo -sysprops 32249

常用 JVM 参数:

-Xms:初始堆大小,默认为物理内存的1/64(<1GB);默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制
-Xmx:最大堆大小,默认(MaxHeapFreeRatio参数可以调整)空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制
-Xmn:新生代的内存空间大小,注意:此处的大小是(eden+ 2 survivor space)。与jmap -heap中显示的New gen是不同的。整个堆大小=新生代大小 + 老生代大小 + 永久代大小。在保证堆大小不变的情况下,增大新生代后,将会减小老生代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。
-XX:SurvivorRatio:新生代中Eden区域与Survivor区域的容量比值,默认值为8。两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10。
-Xss:每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。应根据应用的线程所需内存大小进行适当调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。一般小的应用, 如果栈不是很深, 应该是128k够用的,大的应用建议使用256k。这个选项对性能影响比较大,需要严格的测试。和threadstacksize选项解释很类似,官方文档似乎没有解释,在论坛中有这样一句话:"-Xss is translated in a VM flag named ThreadStackSize”一般设置这个值就可以了。
-XX:PermSize:设置永久代(perm gen)初始值。默认值为物理内存的1/64。
-XX:MaxPermSize:设置持久代最大值。物理内存的1/4

jstat命令

jstat命令是使用频率比较高的命令,主要用来查看JVM运行时的状态信息,包括内存状态、垃圾回收等。

命令格式:

jstat [option] LVMID [interval] [count]

其中LVMID是进程id,interval是打印间隔时间(毫秒),count是打印次数(默认一直打印)

option参数解释:

-class class loader的行为统计
-compiler HotSpt JIT编译器行为统计
-gc 垃圾回收堆的行为统计
-gccapacity 各个垃圾回收代容量(young,old,perm)和他们相应的空间统计
-gcutil 垃圾回收统计概述
-gccause 垃圾收集统计概述(同-gcutil),附加最近两次垃圾回收事件的原因
-gcnew 新生代行为统计
-gcnewcapacity 新生代与其相应的内存空间的统计
-gcold 年老代和永生代行为统计
-gcoldcapacity 年老代行为统计
-gcpermcapacity 永生代行为统计
-printcompilation HotSpot编译方法统计

常用案例

jstat -class 32249 3000 3 类加载统计:

[root@localhost bin]# jstat -class 32249 3000 3
Loaded  Bytes  Unloaded  Bytes     Time   
 14952 26983.0      385   586.1      12.69
 14952 26983.0      385   586.1      12.69
 14952 26983.0      385   586.1      12.69

Loaded 加载类的数量
Bytes 加载类合计大小
Unloaded 卸载类的数量
Bytes 卸载类合计大小
Time 表示加载和卸载类总共的耗时

jstat -compiler 32249 3000 3 编译统计

[root@localhost bin]# jstat -compiler 32249 3000 3
Compiled Failed Invalid   Time   FailedType FailedMethod
   18201     11       0   141.17          1 com/mysql/jdbc/AbandonedConnectionCleanupThread run
   18201     11       0   141.17          1 com/mysql/jdbc/AbandonedConnectionCleanupThread run
   18201     11       0   141.17          1 com/mysql/jdbc/AbandonedConnectionCleanupThread run

Compiled 表示编译任务执行的次数
Failed 表示编译失败的次数
Invalid 表示编译不可用的次数
Time 表示编译的总耗时
FailedType 表示最后一次编译的类型
FailedMethod 表示最后一次编译失败的类名和方法名

jstat -gc 32249 垃圾回收统计

-gc和-gcutil参数类似,只不过输出字段不是百分比,而是实际的值。
[root@localhost bin]# jstat -gc 32249  
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
10240.0 7680.0  0.0    0.0   329728.0 210549.5  699392.0   67871.0   82944.0 81197.9 9984.0 9587.7   1359   10.897  239    38.398   49.295


字段解释:

S0C survivor0大小
S1C survivor1大小
S0U survivor0已使用大小
S1U survivor1已使用大小
EC Eden区大小
EU Eden区已使用大小
OC 老年代大小
OU 老年代已使用大小
MC 方法区大小
MU 方法区已使用大小
CCSC 压缩类空间大小
CCSU 压缩类空间已使用大小
YGC 年轻代垃圾回收次数
YGCT 年轻代垃圾回收消耗时间
FGC 老年代垃圾回收次数
FGCT 老年代垃圾回收消耗时间
GCT 垃圾回收消耗总时间

jstat -gccapacity 32249 3000 3 堆内存统计

[root@localhost bin]# jstat -gccapacity  32249 3000 3
 NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC       MCMN     MCMX      MC     CCSMN    CCSMX     CCSC    YGC    FGC 
349184.0 349184.0 349184.0 10240.0 7680.0 329728.0   699392.0   699392.0   699392.0   699392.0      0.0 1122304.0  82944.0      0.0 1048576.0   9984.0   1359   239
349184.0 349184.0 349184.0 10240.0 7680.0 329728.0   699392.0   699392.0   699392.0   699392.0      0.0 1122304.0  82944.0      0.0 1048576.0   9984.0   1359   239
349184.0 349184.0 349184.0 10240.0 7680.0 329728.0   699392.0   699392.0   699392.0   699392.0      0.0 1122304.0  82944.0      0.0 1048576.0   9984.0   1359   239

NGCMN:新生代最小值(KB)
NGVMX:新生代最大值(KB)
NGC:当前新生代大小(KB)
S0C:同上
S1C:同上
EC:同上
OGCMN:老年代最小值(KB)
OGCMX:老年代最大值(KB)
OGC:当前老年代大小(KB)
OC:同上
MCMN     :方法区最小值(KB)
MCMX     :方法区最大值(KB)
MCC       :当前方法区大小(KB)
CCSMN  : 压缩类空间最大值
CCSMX  : 压缩类空间最小值
CCSC     :当前压缩类空间大小
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数

jstat -gccause 32249 3000 3 显示垃圾回收的相关信息

[root@localhost bin]# jstat -gccause 32249 3000 3
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT    LGCC                 GCC                 
 24.06   0.00  30.18   9.70  97.89  96.03   1360   10.904   239   38.398   49.302 Allocation Failure   No GC               
 24.06   0.00  30.18   9.70  97.89  96.03   1360   10.904   239   38.398   49.302 Allocation Failure   No GC               
 24.06   0.00  30.98   9.70  97.89  96.03   1360   10.904   239   38.398   49.302 Allocation Failure   No GC  

LGCC:上一次GC的原因,是G1垃圾回收器回收
GCC :当前GC的原因

jstat -gcnew 32249 3000 3 显示新生代的详细信息

[root@localhost bin]# jstat -gcnew 32249 3000 3
 S0C    S1C    S0U    S1U   TT MTT  DSS      EC       EU     YGC     YGCT  
10240.0 9728.0 2464.2    0.0 15  15 9728.0 329216.0 138943.0   1360   10.904
10240.0 9728.0 2464.2    0.0 15  15 9728.0 329216.0 142566.3   1360   10.904
10240.0 9728.0 2464.2    0.0 15  15 9728.0 329216.0 142581.3   1360   10.904


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

jstat -gcnewcapacity 32249 3000 3 新生代各个区的详细信息

[root@localhost bin]# jstat -gcnewcapacity 32249 3000 3
  NGCMN      NGCMX       NGC      S0CMX     S0C     S1CMX     S1C       ECMX        EC      YGC   FGC 
  349184.0   349184.0   349184.0 116224.0  10240.0 116224.0   9728.0   348160.0   329216.0  1360   239
  349184.0   349184.0   349184.0 116224.0  10240.0 116224.0   9728.0   348160.0   329216.0  1360   239
  349184.0   349184.0   349184.0 116224.0  10240.0 116224.0   9728.0   348160.0   329216.0  1360   239


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

jstat -gcold 32249 3000 3 老年代垃圾回收统计

[root@localhost bin]# jstat -gcold 32249 3000 3
   MC       MU      CCSC     CCSU       OC          OU       YGC    FGC    FGCT     GCT   
 82944.0  81197.9   9984.0   9587.7    699392.0     67871.0   1360   239   38.398   49.302
 82944.0  81197.9   9984.0   9587.7    699392.0     67871.0   1360   239   38.398   49.302
 82944.0  81197.9   9984.0   9587.7    699392.0     67871.0   1360   239   38.398   49.302

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

jstat -gcoldcapacity 32249 3000 3 老年代各个区的详细信息

[root@localhost bin]# jstat -gcoldcapacity 32249 3000 3
   OGCMN       OGCMX        OGC         OC       YGC   FGC    FGCT     GCT   
   699392.0    699392.0    699392.0    699392.0  1361   239   38.398   49.309
   699392.0    699392.0    699392.0    699392.0  1361   239   38.398   49.309
   699392.0    699392.0    699392.0    699392.0  1361   239   38.398   49.309


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

jstat -gcmetacapacity 32249 3000 3 元数据空间统计

[root@localhost bin]# jstat -gcmetacapacity 32249 3000 3
   MCMN       MCMX        MC       CCSMN      CCSMX       CCSC     YGC   FGC    FGCT     GCT   
       0.0  1122304.0    82944.0        0.0  1048576.0     9984.0  1361   239   38.398   49.309
       0.0  1122304.0    82944.0        0.0  1048576.0     9984.0  1361   239   38.398   49.309
       0.0  1122304.0    82944.0        0.0  1048576.0     9984.0  1361   239   38.398   49.309

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

jstat -gcutil 32249 总结垃圾回收统计

[root@localhost bin]# jstat -gcutil 32249
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
  0.00   0.00  56.15   9.70  97.89  96.03   1359   10.897   239   38.398   49.295

字段解释:

S0 survivor0使用百分比
S1 survivor1使用百分比
E Eden区使用百分比
O 老年代使用百分比
M 元数据区使用百分比
CCS 压缩使用百分比
YGC 年轻代垃圾回收次数
YGCT 年轻代垃圾回收消耗时间
FGC 老年代垃圾回收次数
FGCT 老年代垃圾回收消耗时间
GCT 垃圾回收消耗总时间

jstat -printcompilation 32249 3000 3 JVM编译方法统计

[root@localhost bin]# jstat -printcompilation 32249 3000 3
Compiled  Size  Type Method
   18201     50    1 sun/reflect/GeneratedSerializationConstructorAccessor185 newInstance
   18201     50    1 sun/reflect/GeneratedSerializationConstructorAccessor185 newInstance
   18201     50    1 sun/reflect/GeneratedSerializationConstructorAccessor185 newInstance

Compiled:最近编译方法的数量
Size:最近编译方法的字节码数量
Type:最近编译方法的编译类型。
Method:方法名标识。

jstack命令

So,jstack命令主要用来查看Java线程的调用堆栈的,可以用来分析线程问题(如死锁)。

线程状态
想要通过jstack命令来分析线程的情况的话,首先要知道线程都有哪些状态,下面这些状态是我们使用jstack命令查看线程堆栈信息时可能会看到的线程的几种状态:

NEW,未启动的。不会出现在Dump中。

RUNNABLE,在虚拟机内执行的。运行中状态,可能里面还能看到locked字样,表明它获得了某把锁。

BLOCKED,受阻塞并等待监视器锁。被某个锁(synchronizers)給block住了。

WATING,无限期等待另一个线程执行特定操作。等待某个condition或monitor发生,一般停留在park(), wait(), sleep(),join() 等语句里。

TIMED_WATING,有时限的等待另一个线程的特定操作。和WAITING的区别是wait() 等语句加上了时间限制 wait(timeout)。

TERMINATED,已退出的。

Monitor

在多线程的 JAVA程序中,实现线程之间的同步,就要说说 Monitor。 Monitor是 Java中用以实现线程之间的互斥与协作的主要手段,它可以看成是对象或者 Class的锁。每一个对象都有,也仅有一个 monitor。

进入区(Entrt Set):表示线程通过synchronized要求获取对象的锁。如果对象未被锁住,则进入拥有者;否则则在进入区等待。一旦对象锁被其他线程释放,立即参与竞争。

拥有者(The Owner):表示某一线程成功竞争到对象锁。

等待区(Wait Set):表示线程通过对象的wait方法,释放对象的锁,并在等待区等待被唤醒。

命令格式
jstack [ option ] pid

-l long listings,会打印出额外的锁信息,在发生死锁时可以用jstack -l pid来观察锁持有情况
-m mixed mode,不仅会输出Java堆栈信息,还会输出C/C++堆栈信息(比如Native方法)

pid 需要被打印配置信息的java进程id,可以用jps查询.

使用实例
top 用top 查找出哪个进程消耗的cpu高

[root@localhost /]# top
top - 14:13:12 up 28 days, 20:54,  2 users,  load average: 0.06, 0.03, 0.05
Tasks: 182 total,   1 running, 181 sleeping,   0 stopped,   0 zombie
%Cpu(s):  3.9 us,  8.9 sy,  0.0 ni, 87.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  4989664 total,   821844 free,  2660488 used,  1507332 buff/cache
KiB Swap:  4063228 total,  4062924 free,      304 used.  1994220 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                                                   
22877 root      20   0 3791172 864872  14908 S   2.0 17.3  15:57.31 java                                                                                                                      
 4277 root      20   0 5054636 1.088g  47704 S   0.7 22.9 184:34.46 java                                                                                                                      
30334 root      20   0  157716   2280   1552 R   0.7  0.0   0:00.15 top                                                                                                                       
    1 root      20   0  128104   6776   4020 S   0.3  0.1   7:33.65 systemd                                                                                                                   
    2 root      20   0       0      0      0 S   0.0  0.0   0:00.67 kthreadd                                                                                                                  
    3 root      20   0       0      0      0 S   0.0  0.0   0:09.74 ksoftirqd/0                                                                                                               
    5 root       0 -20       0      0      0 S   0.0  0.0   0:00.00 kwo

top -HP 22877 找出此进程中cpu最高得线程

[root@localhost /]# top -HP 22877
top: unknown option 'P'
Usage:
  top -hv | -bcHiOSs -d secs -n max -u|U user -p pid(s) -o field -w [cols]
[root@localhost /]# top -Hp 22877
top - 14:14:51 up 28 days, 20:56,  2 users,  load average: 0.01, 0.02, 0.05
Threads:  71 total,   0 running,  71 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.5 us,  0.7 sy,  0.0 ni, 98.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  4989664 total,   822312 free,  2660044 used,  1507308 buff/cache
KiB Swap:  4063228 total,  4062924 free,      304 used.  1994688 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                                                                    
23075 root      20   0 3791172 864872  14908 S  1.3 17.3   6:24.30 java                                                                                                                       
 8656 root      20   0 3791172 864872  14908 S  0.3 17.3   0:44.16 java                                                                                                                       
22877 root      20   0 3791172 864872  14908 S  0.0 17.3   0:00.00 java                                                                                                                       
22879 root      20   0 3791172 864872  14908 S  0.0 17.3   0:01.06 java                                                                                                                       
22880 root      20   0 3791172 864872  14908 S  0.0 17.3   0:05.61 java                                                                                                                       
22881 root      20   0 3791172 864872  14908 S  0.0 17.3   0:05.67 java                                                                                                                       
22882 root      20   0 3791172 864872  14908 S  0.0 17.3   0:09.10 java                                                                                                                       
22883 root      20   0 3791172 864872  14908 S  0.0 17.3   0:00.06 java                                                                                                                       
22884 root      20   0 3791172 864872  14908 S  0.0 17.3   0:00.07 java                                                                                                                       
22885 root      20   0 3791172 864872  14908 S  0.0 17.3   0:00.00 java                                                                                                                       
22886 root      20   0 3791172 864872  14908 S  0.0 17.3   0:00.00 java                                                                                                                       
22887 root      20   0 3791172 864872  14908 S  0.0 17.3   0:00.00 java                                                                                                                       
22888 root      20   0 3791172 864872  14908

TIME列就是各个Java线程耗费的CPU时间,CPU时间最长的是线程ID为21742的线程,用
printf “%x\n” 21742
得到21742的十六进制值为54ee,下面会用到。

OK,下一步终于轮到jstack上场了,它用来输出进程21711的堆栈信息,然后根据线程ID的十六进制值grep,如下:

jstack 22877

[root@localhost /]# jstack 22877
2019-06-21 14:09:29
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.131-b11 mixed mode):

"Attach Listener" #65514 daemon prio=9 os_prio=0 tid=0x00007f3b701f0000 nid=0x6b46 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"DiscoveryClient-CacheRefreshExecutor-103" #65294 daemon prio=5 os_prio=0 tid=0x00007f3b4c042800 nid=0x21d1 waiting on condition [0x00007f3b5045a000]
   java.lang.Thread.State: WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x00000000c3402428> (a java.util.concurrent.SynchronousQueue$TransferStack)
	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
	at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:458)
	at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
	at java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:924)
	at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:748)
......	

Jmap命令

jmap [ option ] pid

where 

使用实例

jmap -heap 22877

[root@localhost /]# jmap -heap 22877
Attaching to process ID 22877, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.131-b11

using thread-local object allocation.
Parallel GC with 2 thread(s)

Heap Configuration: #堆内存初始化配置
   MinHeapFreeRatio         = 0	 #-XX:MinHeapFreeRatio设置JVM堆最小空闲比率  
   MaxHeapFreeRatio         = 100 #-XX:MaxHeapFreeRatio设置JVM堆最大空闲比率  
   MaxHeapSize              = 1073741824 (1024.0MB)  #-XX:MaxHeapSize=设置JVM堆的最大大小
   NewSize                  = 357564416 (341.0MB)  #-XX:NewSize=设置JVM堆的‘新生代’的默认大小
   MaxNewSize               = 357564416 (341.0MB) #-XX:MaxNewSize=设置JVM堆的‘新生代’的最大大小
   OldSize                  = 716177408 (683.0MB) #-XX:OldSize=设置JVM堆的‘老生代’的大小
   NewRatio                 = 2  #-XX:NewRatio=:‘新生代’和‘老生代’的大小比率
   SurvivorRatio            = 8 #-XX:SurvivorRatio=设置年轻代中Eden区与Survivor区的大小比值
   MetaspaceSize            = 536870912 (512.0MB) #-XX:PermSize=:设置JVM堆的‘元数据’的初始大小  
   CompressedClassSpaceSize = 1073741824 (1024.0MB)  # 压缩类空间大小
   MaxMetaspaceSize         = 536870912 (512.0MB)  #-XX:PermSize=:设置JVM堆的‘元数据’的最大大小
   G1HeapRegionSize         = 0 (0.0MB)  //G1垃圾收集器每个Region大小

Heap Usage: //堆内存使用情况
PS Young Generation
Eden Space: //Eden区内存分布
   capacity = 350224384 (334.0MB) //Eden区总容量
   used     = 344638936 (328.67330169677734MB) //Eden区已使用
   free     = 5585448 (5.326698303222656MB)  //Eden区剩余容量
   98.40518014873574% used  //Eden区使用比率
From Space: //其中一个Survivor区的内存分布
   capacity = 3670016 (3.5MB)
   used     = 2146544 (2.0471038818359375MB)
   free     = 1523472 (1.4528961181640625MB)
   58.488682338169646% used
To Space: //另一个Survivor区的内存分布
   capacity = 3670016 (3.5MB)
   used     = 0 (0.0MB)
   free     = 3670016 (3.5MB)
   0.0% used
PS Old Generation //老年代容量
   capacity = 716177408 (683.0MB) //老年代容量
   used     = 76042432 (72.51971435546875MB) //老年代已使用
   free     = 640134976 (610.4802856445312MB) //老年代空闲
   10.617820549849013% used //老年代使用比率

38879 interned Strings occupying 4497664 bytes.

jmap -histo 22877 |more 展示class的内存情况
说明:instances(实例数)、bytes(大小)、classs name(类名)。它基本是按照使用使用大小逆序排列的。

[root@localhost /]# jmap -histo 22877 |more

 num     #instances         #bytes  class name
----------------------------------------------
   1:        806954       94090336  [C
   2:        342614       80214112  [B
   3:        616004       14784096  java.lang.String
   4:         66861        5883768  java.lang.reflect.Method
   5:         20744        5530864  [I
   6:        115703        5505376  [Ljava.lang.Object;
   7:        165142        5284544  java.util.concurrent.ConcurrentHashMap$Node
   8:         94457        3778280  java.util.LinkedHashMap$Entry
   9:         86931        2781792  java.util.HashMap$Node
  10:         31866        2749216  [Ljava.util.HashMap$Node;
  11:         30105        2649240  org.apache.naming.resources.FileDirContext$FileResourceAttributes
  12:         96368        2312832  java.util.ArrayList
  13:         41395        1986960  org.aspectj.weaver.reflect.ShadowMatchImpl
  14:         16030        1776000  java.lang.Class
  15:         30855        1727880  java.util.LinkedHashMap
  16:          6465        1646048  [Ljava.util.concurrent.ConcurrentHashMap$Node;
  17:         44691        1430112  java.io.File



#instance 是对象的实例个数 
#bytes 是总占用的字节数 
class name 对应的就是 Class 文件里的 class 的标识 
B 代表 byte
C 代表 char
D 代表 double
F 代表 float
I 代表 int
J 代表 long
Z 代表 boolean
前边有 [ 代表数组, [I 就相当于 int[]
对象用 [L+ 类名表示

从打印结果可看出,类名中存在[C、[B等内容,

只知道它占用了那么大的内存,但不知道由什么对象创建的。下一步需要将其他dump出来,使用内存分析工具进一步明确它是由谁引用的、由什么对象

jmap -histo:live pid>a.log
可以观察heap中所有对象的情况(heap中所有生存的对象的情况)。包括对象数量和所占空间大小。 可以将其保存到文本中去,在一段时间后,使用文本对比工具,可以对比出GC回收了哪些对象。

jmap -dump:live,format=b,file=a.log pid
说明:内存信息dump到a.log文件中。

这个命令执行,JVM会将整个heap的信息dump写入到一个文件,heap如果比较大的话,就会导致这个过程比较耗时,并且执行的过程中为了保证dump的信息是可靠的,所以会暂停应用。

你可能感兴趣的:(jvm)