我使用tomcat用户启动tomcat,并以root用户身份执行jstack
。我检查了gc日志,发现了Full GC。
我搜索并找到sudo -u tomcat jstack -l <pid>
将解决问题。但是为什么jstack与root用户会导致完整的gc?
环境:
[root@bogon ~]# cat /etc/redhat-release
CentOS release 6.8 (Final)
[root@bogon ~]# java -version
java version "1.8.0_65"
Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.65-b01, mixed mode)
[root@bogon ~]# service tomcat version
vagrant: Display Tomcat Version
Using CATALINA_BASE: /apps/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /apps/tomcat/temp
Using JRE_HOME: /usr/java/jdk1.8.0_65/
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Server version: Apache Tomcat/8.5.11
Server built: Jan 10 2017 21:02:52 UTC
Server number: 8.5.11.0
OS Name: Linux
OS Version: 2.6.32-642.15.1.el6.x86_64
Architecture: amd64
JVM Version: 1.8.0_65-b17
JVM Vendor: Oracle Corporation
[root@bogon tomcat]# jstack -l 2644
2644: Unable to open socket file: target process not responding or HotSpot VM not loaded
The -F option can be used when the target process is not responding
GC记录
CommandLine flags: -XX:+DisableExplicitGC -XX:GCLogFileSize=2097152 -XX:+HeapDumpOnOutOfMemoryError -XX:InitialHeapSize=1149239296 -XX:InitiatingHeapOccupancyPercent=45 -XX:+ManagementServer -XX:MaxGCPauseMillis=200 -XX:MaxHeapSize=1149239296 -XX:MaxMetaspaceFreeRatio=80 -XX:MetaspaceSize=100663296 -XX:MinMetaspaceFreeRatio=50 -XX:NumberOfGCLogFiles=10 -XX:+PrintClassHistogram -XX:+PrintGC -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintTenuringDistribution -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC -XX:+UseGCLogFileRotation -XX:+UseStringDeduplication
2017-07-05T20:13:10.591+0800: 38.999: [Full GC (Heap Inspection Initiated GC) 47M->13M(1096M), 0.0710197 secs]
[Eden: 48.0M(54.0M)->0.0B(54.0M) Survivors: 0.0B->0.0B Heap: 47.5M(1096.0M)->13.2M(1096.0M)], [Metaspace: 15845K->15845K(1062912K)]
[Times: user=0.04 sys=0.02, real=0.07 secs]
num #instances #bytes class name
----------------------------------------------
1: 27256 5409512 [C
2: 2889 3734776 [B
3: 28 935336 [J
4: 26366 632784 java.lang.String
5: 4464 392832 java.lang.reflect.Method
6: 2964 338128 java.lang.Class
7: 9495 303840 java.util.HashMap$Node
8: 1566 203296 [I
9: 2576 167120 [Ljava.lang.Object;
10: 971 120680 [Ljava.util.HashMap$Node;
11: 3610 115520 java.util.concurrent.ConcurrentHashMap$Node
12: 3335 69056 [Ljava.lang.Class;
13: 924 67912 [Ljava.lang.String;
14: 1697 67880 java.lang.ref.Finalizer
15: 1608 64320 java.util.LinkedHashMap$Entry
16: 1232 59136 java.util.HashMap
17: 652 52160 java.lang.reflect.Constructor
18: 3243 51888 java.lang.Object
19: 1453 46496 java.util.Hashtable$Entry
20: 1027 41080 java.util.TreeMap$Entry
21: 711 39816 java.util.zip.ZipFile$ZipFileInputStream
22: 708 39648 java.util.zip.ZipFile$ZipFileInflaterInputStream
23: 308 37176 [Ljava.lang.reflect.Method;
24: 764 36672 org.apache.tomcat.util.modeler.AttributeInfo
25: 56 31968 [Ljava.util.concurrent.ConcurrentHashMap$Node;
26: 442 31824 java.lang.reflect.Field
27: 30 31200 [[C
答案 0 :(得分:1)
在您的情况下,GC由-XX:+PrintClassHistogram
选项引起。此标志强制执行堆检查并伴有Full GC以响应SIGQUIT
信号。
您可以从this answer找到,jstack
使用SIGQUIT
启动与目标JVM的通信。同样的答案解释了为什么jstack
在tomcat用户下工作,但不在root下。
简而言之,SIGQUIT
(也称为kill -3)扮演两个角色:启动动态连接和转储JVM状态。如果动态连接失败,则JVM继续进行堆检查,这反过来会导致Full GC,因为-XX:+PrintClassHistogram
选项已打开。