不同用户执行jstack导致Full GC
Execute jstack with different user cause Full GC
我用tomcat用户启动tomcat,用root用户执行jstack
。我查看了gc日志,发现Full GC发生了。
我搜索并发现 sudo -u tomcat jstack -l <pid>
将解决问题。但是为什么root用户的jstack会造成full 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
在您的情况下,GC 是由 -XX:+PrintClassHistogram
选项引起的。此标志强制堆检查伴随 Full GC 以响应 SIGQUIT
信号。
正如您从 this answer 中发现的那样,jstack
使用 SIGQUIT
启动与目标 JVM 的通信。同样的答案解释了为什么 jstack
在 tomcat 用户下工作,但在 root 下不工作。
简而言之,SIGQUIT
(也称为 kill -3)有两个作用:启动动态附加和转储 JVM 状态。如果 Dynamic Attach 失败,则 JVM 继续进行堆检查,这反过来会导致 Full GC,因为 -XX:+PrintClassHistogram
选项已打开。
我用tomcat用户启动tomcat,用root用户执行jstack
。我查看了gc日志,发现Full GC发生了。
我搜索并发现 sudo -u tomcat jstack -l <pid>
将解决问题。但是为什么root用户的jstack会造成full 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
在您的情况下,GC 是由 -XX:+PrintClassHistogram
选项引起的。此标志强制堆检查伴随 Full GC 以响应 SIGQUIT
信号。
正如您从 this answer 中发现的那样,jstack
使用 SIGQUIT
启动与目标 JVM 的通信。同样的答案解释了为什么 jstack
在 tomcat 用户下工作,但在 root 下不工作。
简而言之,SIGQUIT
(也称为 kill -3)有两个作用:启动动态附加和转储 JVM 状态。如果 Dynamic Attach 失败,则 JVM 继续进行堆检查,这反过来会导致 Full GC,因为 -XX:+PrintClassHistogram
选项已打开。