GC 调试过程记录

查看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分析

  •  主要查看GC导致的stop-the-world,这将导致我们的程序延时增大
# 查看进程号

# 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 在线分析地址

GC 调试过程记录_第1张图片 

分析结果 

 JVM内存大小

  • 申请了1G
  • 使用了0.97g 

GC 调试过程记录_第2张图片

关键指标 

 GC 调试过程记录_第3张图片

 可查看GC前后的交互图

GC 调试过程记录_第4张图片

 GC相关统计 

  •  可从FGC的频率,其他 GC的稳定性上做优化工作

GC 调试过程记录_第5张图片 

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的线程数
# 查看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、 调优是个反复的过程,需要不停的结合监控进行,无监控,不调优

 

 

你可能感兴趣的:(高性能编程,性能调优,java,GC调优,jvm)