查看JVM配置
[root@localhost data]# java -version
java version "1.8.0_231" # 版本
Java(TM) SE Runtime Environment (build 1.8.0_231-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.231-b11, mixed mode)
# model类型
# -Xmixed 混合模式(先编译后执行)
# -Xint 解释执行
# -Xcomp 第一次使用就编译成本地代码
运行环境参数
# Java8 固定设置堆1G
# 默认大小通常太小,尽量授予尽可能多的内存,增加CPU的时候,内存也应该增加
# -Xloggc:log路径 -->指定了log文件 -Xmx指定了最大堆内存
[root@localhost data]# java -jar -Xloggc:/data/gc.log -Xmx1024m rabbit_publish-0.0.1-SNAPSHOT.jar
示例代码1(150个内存消耗)
package com.example.mq;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.util.Random;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @Package: com.example.mq
* @Description: <对象存活在1秒左右的场景,远远超过平时接口的响应时间要求,场景应该为吞吐量优先>
* @Author: milla
* @CreateDate: 2020/07/31 18:45
* @UpdateUser: milla
* @UpdateDate: 2020/07/31 18:45
* @UpdateRemark: <打包之后在服务器上运行>
* @Version: 1.0
*/
@SpringBootApplication
public class RabbitTestApplication {
public static void main(String[] args) {
SpringApplication.run(RabbitTestApplication.class, args);
//每隔100毫秒执行一次
// 启动程序,模拟用户请求
// 每100毫秒钟创建150线程,每个线程创建一个512kb的对象,最多一秒同时存在1500线程,占用内存750m(75%),查看GC的情况
new ScheduledThreadPoolExecutor(1).scheduleAtFixedRate(() -> {
new Thread(() -> {
for (int i = 0; i < 150; i++) {
//开辟512k的内存空间
byte[] bytes = new byte[1024 * 512];
try {
//随机休眠1s以内的时间
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}, 100, 100, TimeUnit.MILLISECONDS);
}
}
# 启动服务 分别开启gc日志 和最大堆内存参数
[root@localhost data]# java -jar -Xloggc:/data/gc.log -Xmx1024m rabbit_publish-0.0.1-SNAPSHOT.jar
GC分析
# 查看进程号
# ps -ef 命令 grep -v 排除grep进程本身
[root@localhost data]# ps -fe | grep -v grep |grep rabbit
root 1147 7196 50 18:51 pts/1 00:01:13 java -jar -Xloggc:/data/gc.log -Xmx1024m rabbit_publish-0.0.1-SNAPSHOT.jar
# jcmd 命令
[root@localhost data]# jcmd | grep rabbit
1147 rabbit_publish-0.0.1-SNAPSHOT.jar
# 只获取进程号 awk 默认按照空格截取字符串 $1 取第一个元素
[root@localhost data]# jcmd | grep rabbit |awk '{print $1}'
1147
# jmap 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况
[root@localhost data]# jmap -heap $(jcmd | grep rabbit |awk '{print $1}')
Attaching to process ID 1147, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.231-b11
using thread-local object allocation.
Parallel GC with 13 thread(s)
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 1073741824 (1024.0MB)
NewSize = 175112192 (167.0MB)
MaxNewSize = 357564416 (341.0MB)
OldSize = 351272960 (335.0MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
PS Young Generation
Eden Space:
capacity = 356515840 (340.0MB)
used = 228224680 (217.65201568603516MB)
free = 128291160 (122.34798431396484MB)
64.01529873118682% used
From Space:
capacity = 524288 (0.5MB)
used = 163840 (0.15625MB)
free = 360448 (0.34375MB)
31.25% used
To Space:
capacity = 524288 (0.5MB)
used = 0 (0.0MB)
free = 524288 (0.5MB)
0.0% used
PS Old Generation
capacity = 716177408 (683.0MB)
used = 586596288 (559.4218139648438MB)
free = 129581120 (123.57818603515625MB)
81.9065613418512% used
14238 interned Strings occupying 1262592 bytes.
# jstat命令时时查看gc情况
[root@localhost data]# jstat -gc -h10 $(jcmd | grep rabbit |awk '{print $1}') 1000
可使用GC可视化分析工具
gceasy 在线分析地址
分析结果
JVM内存大小
关键指标
可查看GC前后的交互图
GC相关统计
GC调优
# 通过该命令查看所有参数信息
[root@localhost data]# java -XX:+PrintFlagsFinal -version
# 通过该命令查看所有参数信息-指定关键字参数
# UseAdaptiveSizePolicy自适应默认开启,所以Eden区会自动变化大小
[root@localhost data]# java -XX:+PrintFlagsFinal -version | grep UseAdaptiveSizePolicy
bool UseAdaptiveSizePolicy = true {product}
bool UseAdaptiveSizePolicyFootprintGoal = true {product}
bool UseAdaptiveSizePolicyWithSystemGC = false {product}
java version "1.8.0_231"
Java(TM) SE Runtime Environment (build 1.8.0_231-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.231-b11, mixed mode)
# 默认情况,实时监控结果:10秒内20次YGC,0次FullGC,总耗时0.107秒 -- 从结果看很文档且基本最优
[root@localhost data]# jstat -gc -h10 $(jcmd | grep rabbit |awk '{print $1}') 1000
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
512.0 512.0 0.0 192.0 348160.0 27540.6 699392.0 683168.1 34688.0 32256.3 4480.0 4026.3 3851 23.335 16 0.782 24.117
512.0 512.0 0.0 96.0 348160.0 125262.0 699392.0 683232.1 34688.0 32256.3 4480.0 4026.3 3853 23.345 16 0.782 24.127
512.0 512.0 0.0 128.0 348160.0 147642.9 699392.0 683304.1 34688.0 32256.3 4480.0 4026.3 3855 23.356 16 0.782 24.138
512.0 512.0 0.0 160.0 348160.0 235859.2 699392.0 683384.1 34688.0 32256.3 4480.0 4026.3 3857 23.367 16 0.782 24.149
512.0 512.0 160.0 0.0 348160.0 0.0 699392.0 683464.1 34688.0 32256.3 4480.0 4026.3 3860 23.384 16 0.782 24.166
512.0 512.0 192.0 0.0 348160.0 81671.0 699392.0 683552.1 34688.0 32256.3 4480.0 4026.3 3862 23.394 16 0.782 24.176
512.0 512.0 160.0 0.0 348160.0 173141.6 699392.0 683632.1 34688.0 32256.3 4480.0 4026.3 3864 23.404 16 0.782 24.186
512.0 512.0 192.0 0.0 348160.0 281901.7 699392.0 683720.1 34688.0 32256.3 4480.0 4026.3 3866 23.415 16 0.782 24.197
512.0 512.0 0.0 128.0 348160.0 46316.1 699392.0 683824.1 34688.0 32256.3 4480.0 4026.3 3869 23.431 16 0.782 24.213
512.0 512.0 0.0 192.0 348160.0 153926.9 699392.0 683912.1 34688.0 32256.3 4480.0 4026.3 3871 23.442 16 0.782 24.224
# S0C:当前S0容量(kB)
# S1C:当前S1容量(kB)
# S0U:S0利用率(kB)
# S1U:S1利用率(kB)
# EC: Eden容量(kB)
# EU:Eden利用率(kB)
# OC:老年代容量(kB)
# OU:老年代利用率(kB)
# MC: Metaspace容量(kB)
# MU:Metaspace利用率(kB)
# CCSC:类指针压缩空间容量(kB)
# CCSU:使用的类指针压缩空间(kB)
# YGC:新生代GC活动的数量
# YGCT:新生代GC时间
# FGC:Full GC的数量
# FGCT:Full GC时间
# GCT:GC总时间
jstat命令详细描述
# 查看GC线程数量
[root@localhost data]# java -XX:+PrintFlagsFinal -version | grep ParallelGCThreads
uintx ParallelGCThreads = 13 {product}
java version "1.8.0_231"
Java(TM) SE Runtime Environment (build 1.8.0_231-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.231-b11, mixed mode)
调小GC线程数为1个
[root@localhost data]# java -jar -Xmx1024m -XX:ParallelGCThreads=1 rabbit_publish-0.0.1-SNAPSHOT.jar
# GC 线程数量调整为1后的GC数据 实时监控结果:10秒内25次YGC,2次FullGC,总耗时1.272秒
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
75776.0 75776.0 0.0 72738.2 197632.0 191392.6 219136.0 131641.2 34432.0 32218.5 4480.0 4025.4 72 2.895 1 0.115 3.010
82944.0 86016.0 0.0 0.0 177152.0 112703.2 375808.0 86402.0 34432.0 32218.5 4480.0 4025.4 74 3.032 2 0.236 3.268
90112.0 39936.0 0.0 39457.2 171008.0 91850.4 375808.0 139667.7 34432.0 32218.6 4480.0 4025.4 77 3.133 2 0.236 3.369
89600.0 89600.0 39457.2 0.0 169472.0 82360.7 375808.0 217006.0 34432.0 32218.6 4480.0 4025.4 80 3.233 2 0.236 3.469
86528.0 87552.0 0.0 37409.1 171008.0 110483.1 375808.0 292300.3 34432.0 32218.6 4480.0 4025.4 83 3.354 2 0.236 3.591
79360.0 80384.0 43553.3 0.0 181760.0 119359.8 432128.0 85150.6 34432.0 32218.6 4480.0 4025.4 86 3.476 3 0.362 3.838
74240.0 76288.0 0.0 42529.3 190464.0 114852.1 432128.0 162489.0 34432.0 32218.6 4480.0 4025.4 89 3.598 3 0.362 3.959
67072.0 67584.0 44065.3 0.0 207360.0 101872.8 432128.0 235219.2 34432.0 32218.6 4480.0 4025.4 92 3.725 3 0.362 4.087
63488.0 65024.0 0.0 45601.4 215552.0 50244.0 432128.0 308461.4 34432.0 32218.6 4480.0 4025.4 95 3.847 3 0.362 4.208
61952.0 62976.0 0.0 41505.3 219648.0 200946.0 432128.0 358655.0 34432.0 32218.6 4480.0 4025.4 97 3.921 3 0.362 4.282
调大GC线程到20个
[root@localhost data]# java -jar -Xmx1024m -XX:ParallelGCThreads=20 rabbit_publish-0.0.1-SNAPSHOT.jar
# GC 线程数量调整为4后的GC数据 实时监控结果:10秒内24次YGC,2次FullGC,总耗时0.548秒
59904.0 59392.0 48417.5 0.0 227840.0 208079.0 440320.0 227262.3 34432.0 32214.6 4480.0 4020.7 82 1.584 5 0.242 1.826
57856.0 58368.0 0.0 50849.5 230400.0 75305.8 440320.0 293928.3 34432.0 32214.6 4480.0 4020.7 85 1.634 5 0.242 1.876
57856.0 57344.0 0.0 44705.4 232448.0 223796.6 440320.0 343169.8 34432.0 32214.6 4480.0 4020.7 87 1.673 5 0.242 1.915
56832.0 56832.0 0.0 0.0 235520.0 103406.2 461824.0 85179.3 34432.0 32214.6 4480.0 4020.7 90 1.724 6 0.280 2.004
56320.0 56832.0 52545.6 0.0 235008.0 208542.2 461824.0 104163.9 34432.0 32214.6 4480.0 4020.7 92 1.779 6 0.280 2.059
56832.0 56320.0 0.0 43745.3 235520.0 114334.6 461824.0 175502.1 34432.0 32214.6 4480.0 4020.7 95 1.823 6 0.280 2.103
55808.0 55808.0 48417.5 0.0 236544.0 22986.8 461824.0 247328.2 34432.0 32215.1 4480.0 4021.2 98 1.882 6 0.280 2.162
55808.0 55808.0 42177.3 0.0 237568.0 163276.4 461824.0 296617.7 34432.0 32215.1 4480.0 4021.2 100 1.936 6 0.280 2.216
54784.0 54784.0 0.0 43169.3 238080.0 102432.5 461824.0 365851.9 34432.0 32215.1 4480.0 4021.2 103 1.989 6 0.280 2.269
54784.0 54784.0 0.0 0.0 239104.0 60714.8 474624.0 85545.2 34432.0 32215.1 4480.0 4021.2 106 2.051 7 0.322 2.374
PS : 数据显示GC线程数不是越大越好,也不是越小越好,应该是有个最优解
降低耗时 -XX:MaxGCPauseMillis=10
[root@localhost data]# java -jar -Xmx1024m -XX:MaxGCPauseMills=10 rabbit_publish-0.0.1-SNAPSHOT.jar
# GC 降低耗时 实时监控结果:10秒内42次YGC,6次FullGC,总耗时0.746秒
# 代表单次GC时间加速,会换来更多的GC次数,该参数本次并没有提升性能
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
46592.0 47616.0 34465.0 0.0 68096.0 12984.8 245248.0 179941.4 34432.0 32212.0 4480.0 4026.8 54 0.816 6 0.303 1.119
45568.0 46080.0 31969.0 0.0 68096.0 23388.2 242688.0 106565.0 34432.0 32212.0 4480.0 4026.8 58 0.867 7 0.348 1.215
44032.0 44032.0 29344.9 0.0 68096.0 43033.4 242688.0 196783.8 34432.0 32212.0 4480.0 4026.8 62 0.905 7 0.348 1.253
41472.0 41984.0 33953.0 0.0 68096.0 64845.4 238592.0 125062.3 34432.0 32212.0 4480.0 4026.8 66 0.940 8 0.390 1.330
40960.0 40960.0 0.0 25696.8 68096.0 42064.7 237056.0 84549.9 34432.0 32212.0 4480.0 4026.8 71 1.000 9 0.436 1.436
38912.0 39424.0 28288.9 0.0 68096.0 22861.7 237056.0 191201.1 34432.0 32212.0 4480.0 4026.8 76 1.065 9 0.436 1.501
36864.0 37376.0 26848.8 32.0 68096.0 67997.7 237056.0 130183.5 34432.0 32212.0 4480.0 4026.8 81 1.116 10 0.485 1.601
35840.0 35840.0 24256.7 0.0 68096.0 11438.3 235520.0 104574.3 34432.0 32212.0 4480.0 4026.8 86 1.189 11 0.533 1.722
34304.0 34304.0 0.0 28800.9 68096.0 34347.7 235520.0 195873.1 34432.0 32212.7 4480.0 4026.8 91 1.237 11 0.533 1.770
32256.0 32768.0 23680.7 0.0 68096.0 34800.2 233472.0 144576.3 34432.0 32217.0 4480.0 4026.8 96 1.290 12 0.575 1.865
改用CMS回收器 -XX:+UseConcMarkSweepGC
[root@localhost data]# java -jar -XX:+UseConcMarkSweepGC -Xmx1024m rabbit_publish-0.0.1-SNAPSHOT.jar
# GC 改用CMS回收器 实时监控结果:10秒内51次YGC,0次FullGC,总耗时0.137秒
# cms这种高频回收导致GC次数增多,该参数本次并没有提升性能
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
17088.0 17088.0 537.9 0.0 137152.0 107435.9 342720.0 199188.9 34672.0 32237.8 4500.0 4025.7 1352 7.261 108 0.958 8.219
17088.0 17088.0 532.2 0.0 137152.0 63492.0 342720.0 199194.5 34672.0 32237.8 4500.0 4025.7 1358 7.279 108 0.958 8.237
17088.0 17088.0 528.1 0.0 137152.0 19625.3 342720.0 199200.6 34672.0 32237.8 4500.0 4025.7 1364 7.296 108 0.958 8.254
17088.0 17088.0 0.0 534.2 137152.0 107361.1 342720.0 199205.6 34672.0 32237.8 4500.0 4025.7 1369 7.309 108 0.958 8.267
17088.0 17088.0 0.0 535.8 137152.0 69660.3 342720.0 199211.7 34672.0 32237.8 4500.0 4025.7 1375 7.325 108 0.958 8.284
17088.0 17088.0 0.0 528.1 137152.0 4645.8 342720.0 199217.3 34672.0 32237.8 4500.0 4025.7 1381 7.341 108 0.958 8.299
17088.0 17088.0 540.2 0.0 137152.0 85663.3 342720.0 199222.3 34672.0 32237.8 4500.0 4025.7 1386 7.353 108 0.958 8.311
17088.0 17088.0 529.8 0.0 137152.0 41761.3 342720.0 199228.4 34672.0 32237.8 4500.0 4025.7 1392 7.369 108 0.958 8.328
17088.0 17088.0 22.2 0.0 137152.0 0.0 342720.0 199234.0 34672.0 32237.8 4500.0 4025.7 1398 7.386 108 0.958 8.344
17088.0 17088.0 0.0 14.1 137152.0 89812.2 342720.0 199239.0 34672.0 32237.8 4500.0 4025.7 1403 7.398 108 0.958 8.356
增大堆使用 -XX:+UseG1GC
[root@localhost data]# java -jar -XX:+UseG1GC -Xmx1024m rabbit_publish-0.0.1-SNAPSHOT.jar
# GC 增大堆使用 实时监控结果:10秒内18次YGC,0次FullGC,总耗时0.148秒
# 增大堆使用,该参数本次并没有提升性能
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
0.0 0.0 0.0 0.0 55296.0 3072.0 993280.0 273571.7 34432.0 32221.7 4480.0 4025.6 64 0.937 0 0.000 0.937
0.0 1024.0 0.0 1024.0 659456.0 30720.0 388096.0 285869.0 34432.0 32221.7 4480.0 4025.6 66 0.952 0 0.000 0.952
0.0 0.0 0.0 0.0 55296.0 6144.0 993280.0 487603.1 34432.0 32221.7 4480.0 4025.6 67 0.962 0 0.000 0.962
0.0 0.0 0.0 0.0 55296.0 1024.0 993280.0 137393.1 34432.0 32221.7 4480.0 4025.6 70 0.987 0 0.000 0.987
0.0 1024.0 0.0 1024.0 659456.0 16384.0 388096.0 209542.6 34432.0 32221.7 4480.0 4025.6 72 1.002 0 0.000 1.002
0.0 0.0 0.0 0.0 55296.0 5120.0 993280.0 424589.1 34432.0 32222.3 4480.0 4026.1 73 1.012 0 0.000 1.012
0.0 0.0 0.0 0.0 55296.0 1024.0 993280.0 142528.2 34432.0 32222.3 4480.0 4026.1 76 1.034 0 0.000 1.034
0.0 1024.0 0.0 1024.0 659456.0 20480.0 388096.0 231426.6 34432.0 32222.3 4480.0 4026.1 78 1.049 0 0.000 1.049
0.0 0.0 0.0 0.0 55296.0 6144.0 993280.0 492554.5 34432.0 32222.3 4480.0 4026.1 79 1.058 0 0.000 1.058
0.0 0.0 0.0 0.0 55296.0 2048.0 993280.0 243727.6 34432.0 32224.6 4480.0
4026.1 82 1.085 0 0.000 1.085
增加分区大小 -XX:G1HeapRegionSize=64m
[root@localhost data]# java -jar -XX:G1HeapRegionSize=64m -Xmx1024m rabbit_publish-0.0.1-SNAPSHOT.jar
# GC 增加分区大小 实时监控结果:10秒内21次YGC,1次FullGC,总耗时0.395秒
# 增加分区大小,该参数本次并没有提升性能
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
64000.0 64000.0 54433.7 0.0 219648.0 145581.4 451584.0 105630.3 34432.0 32212.6 4480.0 4025.5 62 1.107 4 0.194 1.301
64512.0 64512.0 51393.6 0.0 220160.0 182058.7 451584.0 152823.7 34432.0 32212.6 4480.0 4025.5 64 1.140 4 0.194 1.333
64000.0 52224.0 0.0 51905.6 220160.0 23057.9 451584.0 222081.8 34432.0 32212.6 4480.0 4025.5 67 1.195 4 0.194 1.388
63488.0 64000.0 0.0 51361.6 220160.0 67978.6 451584.0 268763.3 34432.0 32212.6 4480.0 4025.5 69 1.234 4 0.194 1.428
62976.0 63488.0 0.0 54977.7 221184.0 139920.9 451584.0 312364.6 34432.0 32212.6 4480.0 4025.5 71 1.267 4 0.194 1.461
62976.0 63488.0 0.0 49377.5 221696.0 210630.9 451584.0 364682.2 34432.0 32212.6 4480.0 4025.5 73 1.302 4 0.194 1.495
62464.0 62976.0 0.0 0.0 223232.0 82684.0 486912.0 86174.5 34432.0 32212.6 4480.0 4025.5 76 1.346 5 0.240 1.587
63488.0 62464.0 52961.6 0.0 223232.0 182718.9 486912.0 106703.1 34432.0 32212.6 4480.0 4025.5 78 1.381 5 0.240 1.621
61440.0 61952.0 0.0 47777.5 223744.0 72601.5 486912.0 183113.5 34432.0 32213.9 4480.0 4025.5 81 1.419 5 0.240 1.659
59904.0 60416.0 0.0 47297.4 225792.0 181096.9 486912.0 230818.9 34432.0 32213.9 4480.0 4025.5 83 1.456 5 0.240 1.696
PS: 所以进行了这么多的参数调试并没有有很好的性能提升
- 业务代码中每个100毫秒去申请512k的数据是否符合业务需求
- 是否有真实的场景
- 在性能出现问题的时候还应该结合监控的结果多分析分析代码
# 性能调优实际还是要结合系统情况、系统需要来调整
# 1、 GC调优就是逐步调试的过程,对每个参数的含义了解后,再根据官方手册,一个个调试,找到符合应用的最佳配置点。是一个细致活,难度高。
# 2、 性能问题,大多是出现在业务代码上
# 3、 调优是个反复的过程,需要不停的结合监控进行,无监控,不调优