1. View the system process JPS command
JPS checks the system process information 28532 G1Test, indicating that the process name of the process Pid28532 is G1Test
E:\setup\jar>jps
39024 Launcher
42832 Jps
22644
28532 G1Test
43020 RemoteMavenServer36
9756 Launcher
复制代码
It is consistent with the operation of our program, and the name of our program is G1Test
2. View process information ps -ef |grep xxx
In the Linux system, we can use the ps command to view specific process information
#查看系统 java 进程信息
ps -ef |grep java
#查看具体项目的进程信息
ps -ef |grep web-gateway
复制代码
Results of the
[saas@dev-119 ~]$ ps -ef |grep web-gateway
saas 7039 5764 0 14:33 pts/0 00:00:00 grep --color=auto web-gateway
root 25030 25009 0 3月27 ? 00:00:00 /bin/bash /xxx/app/web-gateway/web-gateway.sh
root 25097 25030 3 3月27 ? 17:34:15 java -server
-Dspring.profiles.active=docker
-DskipTests -Dfile.encoding=UTF-8
-Dsun.jnu.encoding=UTF-8
-Duser.timezone=GMT+8
-Djava.net.preferIPv6Addresses=false -agentlib:jdwp=transport=dt_socket,address=20112,server=y,suspend=n -Xms2g -Xmx2g -Ddubbo.registry.address=zoo1:2181,zoo2:2181
-Dspring.cloud.nacos.config.namespace=xxx
-Dsso-env=xxx
-Dspring.cloud.nacos.discovery.group=xxx
-DxxxUrl=https://sso119.devtest.vip
-DxxxUrl=https://xxx
-DxxxUrl=https://xxx
-DxxxUrl=https://xxx
-DxxxUrl=https://xxx
-jar /xxx/web-gateway/web-gateway.jar
复制代码
3.jinfo pid command to view process information
We use jps or ps-ef |grep xxx to find process information. What is the use of finding it? We can view the process parameter jinfo command through the process information
#查看进程详细参数, 执行 jinfo pid进程id
jinfo 36612
复制代码
Results of the
E:\setup\jar>jinfo 36612
Attaching to process ID 36612, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.181-b13
Java System Properties:
java.runtime.name = Java(TM) SE Runtime Environment
java.vm.version = 25.181-b13
sun.boot.library.path = C:\xxxxx
java.vendor.url = http://java.oracle.com/
java.vm.vendor = Oracle Corporation
path.separator = ;
file.encoding.pkg = sun.io
java.vm.name = Java HotSpot(TM) 64-Bit Server VM
sun.os.patch.level =
sun.java.launcher = SUN_STANDARD
user.script =
user.country = CN
user.dir = E:xxxxx
java.vm.specification.name = Java Virtual Machine Specification
java.runtime.version = 1.8.0_181-b13
java.awt.graphicsenv = sun.awt.Win32GraphicsEnvironment
os.arch = amd64
java.endorsed.dirs = C:\xxxxx
line.separator =
java.io.tmpdir = C:\xxxxx
java.vm.specification.vendor = Oracle Corporation
user.variant =
os.name = Windows 10
sun.jnu.encoding = GBK
java.library.path = xxxxx
java.class.version = 52.0
sun.management.compiler = HotSpot 64-Bit Tiered Compilers
os.version = 10.0
user.home = C:\Users\jzj
user.timezone = Asia/Shanghai
java.awt.printerjob = sun.awt.windows.WPrinterJob
file.encoding = UTF-8
java.specification.version = 1.8
user.name = jzj
java.class.path =xxxxx
java.vm.specification.version = 1.8
sun.arch.data.model = 64
sun.java.command = com.jzj.jvmtest.jvmready.G1Test
java.home = C:\xxxxx
user.language = zh
java.specification.vendor = Oracle Corporation
awt.toolkit = sun.awt.windows.WToolkit
java.vm.info = mixed mode
java.version = 1.8.0_181
java.ext.dirs = xxxxx
file.separator = \
java.vendor.url.bug = http://bugreport.sun.com/bugreport/
sun.io.unicode.encoding = UnicodeLittle
sun.cpu.endian = little
sun.desktop = windows
sun.cpu.isalist = amd64
VM Flags:
Non-default VM flags: -XX:CICompilerCount=4 -XX:ConcGCThreads=3 -XX:G1HeapRegionSize=1048576 -XX:+HeapDumpOnOutOfMemoryError -XX:InitialHeapSize=10485760 -XX:MarkStackSize=4194304 -XX:MaxHeapSize=10485760 -XX:MaxNewSize=6291456 -XX:MinHeapDeltaBytes=1048576 -XX:+PrintGC -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseG1GC -XX:-UseLargePagesIndividualAllocation
Command line: -verbose:gc -XX:+UseG1GC -Xms10M -Xmx10M -XX:+PrintGC -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:SurvivorRatio=8 -javaagent:E:\Program Files\JetBrains\IntelliJ IDEA 2019.3.4\lib\idea_rt.jar=58937:E:\Program Files\JetBrains\IntelliJ IDEA 2019.3.4\bin -Dfile.encoding=UTF-8
复制代码
3.1 System variables
All java system variables, etc.
- java.version java version
- user.name username
- user.timezone = Asia/Shanghai time zone information
- java.io.tmpdir = C:\xxxxx temporary file storage path
java.home = C:\xxxxx
user.language = zh
java.specification.vendor = Oracle Corporation
awt.toolkit = sun.awt.windows.WToolkit
java.vm.info = mixed mode
java.version = 1.8.0_181
java.ext.dirs = xxxxx
复制代码
3.2 JVM parameters
VM virtual machine parameter VM Flags
- -XX:G1HeapRegionSize The size of each Region, in MB, needs to be one of 1, 2, 4, 8, 16, 32, the default is 1/2000 of the heap memory
- -XX:InitialHeapSize=10485760 is equivalent to the -Xms setting, indicating the initialization size of Heap, that is, the minimum value of the heap area when the JVM starts
- -XX:HeapDumpOnOutOfMemoryError stack overflow print OOM error
- -XX:MaxNewSize=6291456 The maximum allocable size of the new generation memory in the JVM heap area (PermSize does not belong to the heap area)
- -XX:+UseG1GC Use the G1 garbage collector
- -XX:MinHeapDeltaBytes=1048576 means that when we want to expand or shrink, we decide whether to do it or try to expand the minimum size
- -XX:+PrintGCDetails Print details during GC
- -XX:SurvivorRatio=8 The ratio of young to survivor is 1:1:8 (s0:s1:Eden)
- XX:MaxHeapSize=10485760 最大的堆内存分配
VM Flags:
Non-default VM flags: -XX:CICompilerCount=4 -XX:ConcGCThreads=3 -XX:G1HeapRegionSize=1048576 -XX:+HeapDumpOnOutOfMemoryError -XX:InitialHeapSize=10485760 -XX:MarkStackSize=4194304 -XX:MaxHeapSize=10485760 -XX:MaxNewSize=6291456 -XX:MinHeapDeltaBytes=1048576 -XX:+PrintGC -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseG1GC -XX:-UseLargePagesIndividualAllocation
复制代码
4.jstat命令
jstat是JDK自带的轻量级小工具,专门用于监控JVM的GC情况,对Java应用程序的资源和性能进行实时的命令行的监控,包括了对Heap size和垃圾回收状况的监控,我们先看看有哪些命令可以使用
#执行 jstat options
E:\setup\jar>jstat -options
-class
-compiler
-gc
-gccapacity
-gccause
-gcmetacapacity
-gcnew
-gcnewcapacity
-gcold
-gcoldcapacity
-gcutil
-printcompilation
复制代码
我们对命令进行结束
- class 用于查看类加载情况的统计
- compiler 用于查看HotSpot中即时编译器编译情况的统计
- gc
用于查看JVM中堆的垃圾收集情况的统计
经常使用 - gccapacity
用于查看新生代、老生代及持久代的存储容量情况
经常使用 - gcmetacapacity
显示metaspace的大小及信息
经常使用 - gcnew 用于查看新生代垃圾收集的情况
- gcnewcapacity 用于查看新生代存储容量的情况
- gcold 用于查看老生代及持久代垃圾收集的情况
- gcoldcapacity 用于查看老生代的容量
- gcutil
显示垃圾回收信息
经常使用 - gccause 显示垃圾回收的相关信息(同-gcutil), 同时显示最后一次仅当前正在发生的垃圾收集的原因
- printcompilation 输出JIT编译的方法信息
启动程序
@Slf4j
public class G1Test {
//JVM 参数 -verbose:gc -Xms10M -Xmx10M -XX:+PrintGC -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:SurvivorRatio=8
public static void main(String[] args) throws Exception {
byte[] b = null;
for (int i = 1; i <= 20; i++) {
//设置 3M的对象
log.info("======== " + i + "次添加3M对象");
b = new byte[2 * 1024 * 1024];
Thread.sleep(3000);
}
}
}
复制代码
4.1 jstat -gc pid 查看进程 GC情况
先执行 jps 找到进程PID G1Test PID是 25060
E:\setup\jar>jps
45616 Launcher
22644
25060 G1Test
44308 Jps
复制代码
执行jstat -gc 25060
#执行 jstat -gc pid
E:\setup\jar>jstat -gc 25060
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
0.0 1024.0 0.0 1024.0 3072.0 0.0 6144.0 5777.7 5504.0 5088.0 640.0 565.8 2 0.003 0 0.000 0.003
#执行 jstat -gc pid 参数1(多少秒执行1次) 参数2 一共打印多少次
#执行 jstat -gc 25060 1000 3 ,表示 1000ms执行1次, 一共执行 3次
E:\setup\jar>jstat -gc 25060 1000 3
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
0.0 1024.0 0.0 1024.0 3072.0 0.0 6144.0 5777.7 5504.0 5088.0 640.0 565.8 2 0.003 0 0.000 0.003
0.0 1024.0 0.0 1024.0 3072.0 0.0 6144.0 5777.7 5504.0 5088.0 640.0 565.8 2 0.003 0 0.000 0.003
0.0 1024.0 0.0 1024.0 3072.0 0.0 6144.0 5777.7 5504.0 5088.0 640.0 565.8 2 0.003 0 0.000 0.003
复制代码
我们解释一下这些信息S0C/S1C/S0U等等代表什么意思
年轻代 幸存区S0/S1 及Eden区的使用情况(单位字节Byte)
S0C | S1C | S0U | S1U | EU | EC |
---|---|---|---|---|---|
年轻代幸存区From区S0的 容量Capacity | 年轻代幸存区To区S1的 容量Capacity | 年轻代幸存区From区S0已经使用Use的容量Capacity | 年轻代幸存区To区S1的 已经使用Use的容量Capacity | 年轻代Eden区的容量Capacity | 年轻代Eden区已经使用Used的容量Capacity |
老年代Old区,元空间Metaspace及CCS(当前压缩类)的使用情况 (单位字节Byte)
OC | OU | MC | MU | CCSU | CCSU |
---|---|---|---|---|---|
Old老年代 容量Capacity | Old老年代已经使用Use的容量Capacity | 元空间Metaspace 容量Capacity | 元空间Metaspace已经使用Use的容量Capacity | 当前压缩类空间 容量Capacity | 当前压缩类空间已经使用Used的容量Capacity |
YoungGC,FullGC发生的次数及花费的时间(秒/s)情况
YGC | YGCT | FGC | FGCT | GCT |
---|---|---|---|---|
从程序启动到采样,YoungGC 发生的次数 | 从程序启动到采样,YoungGC 花费的时间 | 从程序启动到采样,FullGC 发生的次数 | 从程序启动到采样,FullGC 花费的时间 | 从程序启动到采样,GC一共用时 |
4.2 jstat -gcutil pid 查看进程 GC垃圾回收情况
执行JPS找到进程PID G1Test PID 44788
E:\setup\jar>jps
22644
44788 G1Test
47492 Jps
35992 Launcher
复制代码
执行 jstat -gcutil 44788 1000 10 查看垃圾回收情况 1000ms 打印一次, 一共打印10次
#执行 jstat -gcutil 44788 1000 10
E:\setup\jar>jstat -gcutil 44788 1000 10
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 0.00 0.00 65.24 94.24 89.56 20 0.081 4 0.037 0.118
0.00 0.00 0.00 65.24 94.24 89.56 21 0.081 4 0.037 0.118
0.00 0.00 0.00 65.35 94.24 89.56 21 0.092 4 0.037 0.129
0.00 0.00 0.00 65.35 94.24 89.56 21 0.092 4 0.037 0.129
0.00 100.00 0.00 31.89 94.24 89.56 23 0.100 5 0.037 0.137
0.00 0.00 0.00 86.70 94.24 89.56 23 0.100 5 0.049 0.149
0.00 0.00 0.00 86.70 94.24 89.56 23 0.100 5 0.049 0.149
0.00 100.00 0.00 70.10 94.24 89.56 24 0.103 5 0.049 0.152
0.00 100.00 0.00 70.10 94.24 89.56 24 0.103 5 0.049 0.152
0.00 100.00 0.00 70.10 94.24 89.56 24 0.103 5 0.049 0.152
复制代码
我们解释一下这些信息 S0/S/E/O/M/CCS/YGC/YGCT/FGC/FGCT/GCT 等代表什么意思
首先说明一点 这里打印出来的不是真实使用的容量Byte,而是为了方便查看,使用的是 百分比占比
,更加直观,方便定位问题
S0 | S1 | E | O | M | CCS |
---|---|---|---|---|---|
年轻代幸存区From区S0 已使用占当前容量的百分比 | 年轻代幸存区From区S1 已使用占当前容量的百分比 | Eden区已经使用占当前容量的百分比 | Old老年代已经使用占当前容量的百分比 | 元空间Metaspace已经使用占当前容量的百分比 | 当前压缩类空间已经使用占当前容量的百分比 |
从上面可以看出来什么问题? 我们看下这两次打印
#执行 jstat -gcutil 44788 1000 10
E:\setup\jar>jstat -gcutil 44788 1000 10
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 0.00 0.00 65.35 94.24 89.56 21 0.092 4 0.037 0.129
0.00 100.00 0.00 31.89 94.24 89.56 23 0.100 5 0.037 0.137
复制代码
- YGC从 21->23 说明1s之内发生了2次YoungGC,FGC从 4->5说明1s之内发生了1次FullGC
- After YGC/FullGC, the S0 area starts to copy the surviving objects to the S1 area, resulting in S1 accounting for 100%
- Explain that after YoungGC, there are a lot of things that need to be copied, from the From to the To area
- Old area from 65%->31%, some objects in the old area are destroyed after FullGC
- Metaspace accounts for 94.24% Metaspace is too small and will soon be full
4.3 jstat -gccause pid View gc reason
Execute JPS to find the process PID G1Test PID 44912
E:\setup\jar>jps
44912 G1Test
22644
37180 Launcher
46220 Jps
复制代码
Execute jstat -gccause 44912 to check the cause of gc
E:\setup\jar>jstat -gccause 44912
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT LGCC GCC
0.00 0.00 0.00 86.70 94.22 89.56 13 0.045 3 0.017 0.062 Allocation Failure No GC
复制代码
- The reason for the last GC of LGGC is Allocation Failure caused by memory allocation failure
- GCC current GC reason No GC is currently not executing GC
E:\setup\jar>jstat -gccause 44912
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT LGCC GCC
0.00 100.00 0.00 70.07 94.22 89.56 19 0.066 4 0.023 0.089 G1 Humongous Allocation No GC
复制代码
- The reason for the last GC of LGGC G1 Humongous Allocation G1's large object allocation caused
- GCC current GC reason No GC is currently not executing GC
So far we have learned the basic JVM tuning commands, including JPS to view the process, jinfo to view the detailed parameters of the process, Jstat to view the JVM gc situation, especially the use of jstat's lightweight JVM tuning tool, we analyze the JVM based on specific logs Causes of GC, JVM tuning