**查询进程pid**
ps -ef | grep tomcat
命令格式
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=
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命令是使用频率比较高的命令,主要用来查看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:方法名标识。
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的信息是可靠的,所以会暂停应用。