详解JVM中的GC调优

 更新时间:2021年06月03日 09:45:20   作者:flydean  
我们经常会听到甚至需要自己动手去做GC调优。那么GC调优的目的到底是什么呢?让程序跑得更快?让GC消耗更少的资源?还是让程序更加稳定?带着这些疑问来读一下这篇文章,将会得到一个系统的甚至是不一样的结果。

那些GC的默认值

其实GC或者说JVM的参数非常非常的多,有控制内存使用的:

有控制JIT的:

有控制分代比例的,也有控制GC并发的:

当然,大部分的参数其实并不需要我们自行去调整,JVM会很好的动态帮我们设置这些变量的值。

如果我们不去设置这些值,那么对GC性能比较有影响的参数和他们的默认值有哪些呢?

GC的选择

我们知道JVM中的GC有很多种,不同的GC选择对java程序的性能影响还是比较大的。

在JDK9之后,G1已经是默认的垃圾回收器了。

我们看一下G1的调优参数。

G1是基于分代技术的,其实JVM还在开发一些不再基于分代技术的GC算法,比如ZGC,我们可以根据需要来选择适合我们的GC算法。

GC的最大线程个数

GC是由专门的GC线程来执行的,并不是说GC线程越多越好,这个默认线程的最大值是由heap size和可用的CPU资源动态决定的。

当然你可以使用下面两个选项来修改GC的线程:

 -XX:ParallelGCThreads=threads 设置STW的垃圾收集线程数

 -XX:ConcGCThreads = n 设置并行标记线程的数量

一般情况下ConcGCThreads可以设置为ParallelGCThreads的1/4。

初始化heap size

默认情况下加初始化的heap size是物理内存的1/64。

你可以使用

 -XX:InitialHeapSize=size

来重新设置。

最大的heap size

默认情况下最大的heap size是物理内存的1/4。

你可以使用:

-XX:MaxHeapSize

来重新设置。

分层编译技术

默认情况下分层编译技术是开启的。你可以使用:

-XX:-TieredCompilation

来关闭分层编译。如果启用了分层编译,那么可能需要关注JIT中的C1和C2编译器带来的影响。

我们到底要什么

java程序在运行过程中,会发生很多次GC,那么我们其实是有两种统计口径:

1.平均每次GC执行导致程序暂停的时间(Maximum Pause-Time Goal)。

2.总的花费在GC上的时间和应用执行时间的比例(Throughput Goal)。

最大暂停时间

单次GC的暂停时间是一个统计平均值,因为单次GC的时间其实是不可控的,但是取了平均值,GC就可以动态去调整heap的大小,或者其他的一些GC参数,从而保证每次GC的时间不会超过这个平均值。

我们可以通过设置:

-XX:MaxGCPauseMillis=<nnn>

来控制这个值。

不管怎么设置这个参数,总体需要被GC的对象肯定是固定的,如果单次GC暂停时间比较短,可能会需要减少heap size的大小,那么回收的对象也比较少。这样就会导致GC的频率增加。从而导致GC的总时间增加,影响程序的Throughput。

吞吐率

吞吐率是由花费在GC上的时间和应用程序上的时间比率来决定的。

我们可以通过设置:

-XX:GCTimeRatio=nnn

来控制。

如果没有达到throughput的目标,那么GC可能会去增加heap size,从而减少GC的执行频率。但是这样会增加单次的Maximum Pause-Time。

如果throughput和maximum pause-time的参数同时都设置的话,JVM会去尝试去动态减少heap size的大小,直到其中的一个目标不能满足为止。

相对而言,G1更加偏重于最大暂停时间,而ZGC更加偏重于吞吐率。

以上就是详解JVM中的GC调优的详细内容,更多关于JVM中的GC调优的资料请关注脚本之家其它相关文章!

相关文章

  • Java实现从数据库导出大量数据记录并保存到文件的方法

    Java实现从数据库导出大量数据记录并保存到文件的方法

    这篇文章主要介绍了Java实现从数据库导出大量数据记录并保存到文件的方法,涉及Java针对数据库的读取及文件写入等操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-11-11
  • Java 进阶必备之ssm框架全面整合

    Java 进阶必备之ssm框架全面整合

    SSM框架是spring MVC ,spring和mybatis框架的整合,是标准的MVC模式,将整个系统划分为表现层,controller层,service层,DAO层四层,使用spring MVC负责请求的转发和视图管理,spring实现业务对象管理,mybatis作为数据对象的持久化引擎
    2021-10-10
  • Springboot如何获取yml、properties参数

    Springboot如何获取yml、properties参数

    这篇文章主要介绍了Springboot如何获取yml、properties参数,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • SpringBoot中实现Redis Stream队列的代码实例

    SpringBoot中实现Redis Stream队列的代码实例

    本文介绍了如何在Spring Boot中使用Redis Stream队列进行消息的生产和消费,涉及到的主要内容包括添加Redis依赖、配置RedisTemplate、创建生产者和消费者监听器等,需要的朋友可以参考下
    2024-09-09
  • Java登录功能实现token生成与验证

    Java登录功能实现token生成与验证

    这篇文章介绍了Java登录功能实现token生成与验证,文中通过示例代码介绍的非常详细。对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-12-12
  • Spring声明式事务配置使用详解

    Spring声明式事务配置使用详解

    这篇文章主要介绍了在spring注解中,使用声明式事务,需要用到两个核心的注解:@Transactional注解和@EnableTransactionManagement注解。将@Transactional注解加在方法上,@EnableTransactionManagement注解加在配置类上
    2022-08-08
  • feign开启日志Logger.Level feignLoggerLevel()中Level爆红的解决

    feign开启日志Logger.Level feignLoggerLevel()中Level爆红的解决

    这篇文章主要介绍了feign开启日志Logger.Level feignLoggerLevel()中Level爆红的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • jdk自带定时器使用方法详解

    jdk自带定时器使用方法详解

    这篇文章主要为大家详细介绍了jdk自带定时器的使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • Java中Socket实现数据通信的示例代码

    Java中Socket实现数据通信的示例代码

    本文主要介绍了Java中Socket实现数据通信的示例代码,Socket可以建立起客户端和服务器之间的连接,实现数据的传输和交互,感兴趣的可以了解一下
    2023-09-09
  • 使用mybatis框架连接mysql数据库的超详细步骤

    使用mybatis框架连接mysql数据库的超详细步骤

    MyBatis是目前java项目连接数据库的最流行的orm框架了,下面这篇文章主要给大家介绍了关于使用mybatis框架连接mysql数据库的超详细步骤,文中通过实例代码和图文介绍的非常详细,需要的朋友可以参考下
    2023-04-04

最新评论