小李的便利店

悠优酸幽

JVM知识点(三)——JVM参数及调优

调优基本概念

在调整性能时,JVM有三个组件:

1、堆大小调整

2、垃圾收集器调整

3、JIT编译器

大多数调优选项都与调整堆大小和为您的情况选择最合适的垃圾收集器有关。

JIT编译器对性能也有很大影响,但很少需要使用较新版本的JVM进行调优。

通常,在调优Java应用程序时,重点是以下两个主要目标之一:

响应性:应用程序或系统对请求的数据进行响应的速度,对于专注于响应性的应用程序,长的暂停时间是不可接受的,重点是在短时间内做出回应。

吞吐量:侧重于在特定时间段内最大化应用程序的工作量,对于专注于吞吐量的应用程序,高暂停时间是可接受的。由于高吞吐量应用程序在较长时间内专注于基准测试,因此不需要考虑快速响应时间。

常用JVM参数

《JVM知识点(三)——JVM参数及调优》
版本不断更新,JVM参数和具体说明请查看官网文档。

GC调优思路

《JVM知识点(三)——JVM参数及调优》

通用GC参数

《JVM知识点(三)——JVM参数及调优》

垃圾收集器Parallel参数调优

《JVM知识点(三)——JVM参数及调优》

垃圾收集器CMS参数调优

《JVM知识点(三)——JVM参数及调优》

垃圾收集器G1参数调优

《JVM知识点(三)——JVM参数及调优》

运行时JIT编译器优化参数

JIT编译指的是字节码编译为本地代码(汇编)执行,只有热点代码才会编译为本地代码。解释器执行节约内存,反之可以使用编译执行来提升效率。

《JVM知识点(三)——JVM参数及调优》
很少需要对较新版本的JVM进行JIT调优

现在开始实操

测试环境

《JVM知识点(三)——JVM参数及调优》
默认大小通常太小,尽量授予尽可能多的内存,增加CPU的时候,内存也应该增加
java -Xmx1024m -jar optimizedemo-1.0.0-SNAPSHOT.jar

如上代码,设置最大堆内存。运行jar包

1、 示例代码

/**
 * @Title: JVM优化
 * @Description: TODO(这里用一句话描述这个方法的作用)
 * @param @param
 * @return @return
 * @author lion
 * @throws
 * @date 2020/5/11 11:53
 */

// 启动程序,模拟用户请求
@SpringBootApplication
public class OptimizedemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(OptimizedemoApplication.class, args);
        Executors.newScheduledThreadPool(1).scheduleAtFixedRate(()-> {
            new Thread(() ->{
                for (int i = 0; i < 150; i++) {
                    try {
                        //  不干活,专门512kb的小对象
                        byte[] temp = new byte[1024 * 512];
                        Thread.sleep(new Random().nextInt(1000)); // 随机睡眠200毫秒秒以内
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        },100,100, TimeUnit.MILLISECONDS);
    }
// 打包 mvn clean package
// 服务器上运行 optimizedemo-1.0.0-SNAPSHOT.jar
// 对象存活在1秒左右的场景,远远超过平时接口的响应时间要求,场景应该为吞吐量优先
}

1.1 GC分析,主要查看GC导致的stop-the-world,这将导致我们的程序延时增大。

查找到optimizedemo-1.0.0-SNAPSHOT.jar的进程号。
《JVM知识点(三)——JVM参数及调优》
jcmd | grep "optimizedemo-1.0.0-SNAPSHOT.jar" | awk '{print $1}'
jmap 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况。
jmap -heap $(jcmd | grep "optimizedemo-1.0.0-SNAPSHOT.jar" | awk '{print $1}')

输出内容如下:

Attaching to process ID 45758, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.152-b16

using thread-local object allocation.
Parallel GC with 4 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100
   MaxHeapSize              = 1073741824 (1024.0MB)
   NewSize                  = 21495808 (20.5MB)
   MaxNewSize               = 357564416 (341.0MB)
   OldSize                  = 43515904 (41.5MB)
   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 = 335020032 (319.5MB)
   used     = 245937232 (234.5440216064453MB)
   free     = 89082800 (84.95597839355469MB)
   73.40970942298758% used
From Space:
   capacity = 524288 (0.5MB)
   used     = 65536 (0.0625MB)
   free     = 458752 (0.4375MB)
   12.5% used
To Space:
   capacity = 524288 (0.5MB)
   used     = 0 (0.0MB)
   free     = 524288 (0.5MB)
   0.0% used
PS Old Generation
   capacity = 261095424 (249.0MB)
   used     = 139708672 (133.236572265625MB)
   free     = 121386752 (115.763427734375MB)
   53.50866356049197% used

11547 interned Strings occupying 1017408 bytes.

收集GC日志(日志离线分析,主要用于检查故障看出是不是因为GC导致的程序卡顿)

java -Xmx1024m -Xloggc:/usr/local/javaproject/gc1.log -jar optimizedemo-1.0.0-SNAPSHOT.jar

分析GC日志

GCViewer工具,辅助分析GC日志文件 https://github.com/chewiebug/GCViewer

jstat 动态监控GC统计信息,间隔1000毫秒统计一次,每10行数据后输出列标

jstat -gc -h10 $(jcmd | grep "optimizedemo-1.0.0-SNAPSHOT.jar" | awk '{print $1}') 1000

Parallel GC 服务器默认

UseAdaptiveSizePolicy自适应默认开启,所以Eden区会自动变化大小
《JVM知识点(三)——JVM参数及调优》
默认情况,实时监控结果:10秒内24次YGC,0次FullGC,总耗时0.052秒

情况一、调大并行线程的数量

1、 调大-XX:ParallelGCThreads=4 
java -Xmx1024m -Xloggc:/usr/local/javaproject/gc2.log -XX:ParallelGCThreads=4 -jar optimizedemo-1.0.0-SNAPSHOT.jar
《JVM知识点(三)——JVM参数及调优》
实时监控结果:10秒内21次GC,总耗时0.313。 如果有多线程,一定要调大参数

情况二、降低耗时

2、 降低耗时,设置-XX:MaxGCPauseMills=10   
java -Xmx1024m -Xloggc:/usr/local/javaproject/gc3.log -XX:MaxGCPauseMillis=10 -jar optimizedemo-1.0.0-SNAPSHOT.jar
《JVM知识点(三)——JVM参数及调优》
实时监控结果:10秒内186次YGC,26次FGC,GC次数变多,总的时间反倒变长。 代表单次GC时间加速,会换来更多的GC次数,这种情况下不合适。

CMS调优

情况三、改用CMS回收器

java -Xmx1024m -Xloggc:/usr/local/javaproject/gc4.log -XX:+UseConcMarkSweepGC -jar optimizedemo-1.0.0-SNAPSHOT.jar
《JVM知识点(三)——JVM参数及调优》
实时监控结果:10秒内14次YGC,2次FGC,总耗时0.164.

情况四、增加线程

java -Xmx1024m -Xloggc:/usr/local/javaproject/gc4.log -XX:+UseConcMarkSweepGC -XX:ConcGCThreads=3 -jar optimizedemo-1.0.0-SNAPSHOT.jar
《JVM知识点(三)——JVM参数及调优》
实时监控结果:10秒内55次YGC,3次FGC,总耗时0.443.

G1调优 建议大堆使用

情况五、改用G1
java -Xmx1024m -Xloggc:/usr/local/javaproject/gc5.log -XX:+UseG1GC -jar optimizedemo-1.0.0-SNAPSHOT.jar
《JVM知识点(三)——JVM参数及调优》
情况六、增加分区大小
java -Xmx1024m -Xloggc:/usr/local/gc6.log -XX:+UseG1GC -XX:G1HeapRegionSize=64m -jar optimizedemo-1.0.0-SNAPSHOT.jar
《JVM知识点(三)——JVM参数及调优》

总结:

1、 GC调优就是逐步调试的过程,对每个参数的含义了解后,再根据官方手册,一个个调试,找到符合应用的最佳配置点。是一个细致活,难度高。

2、 性能问题,98.75%上是业务代码上面。

3、 无监控,不调优。

点赞

发表评论

电子邮件地址不会被公开。