网站首页 > 教程文章 正文
简介
我们经常会听到甚至需要自己动手去做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,那么我们其实是有两种统计口径:
- 平均每次GC执行导致程序暂停的时间(Maximum Pause-Time Goal)。
- 总的花费在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更加偏重于吞吐率。
本文作者:flydean程序那些事
本文链接:
http://www.flydean.com/jvm-diagnostic-gc/本文来源:flydean的博客
欢迎关注我的公众号:程序那些事,更多精彩等着您!
猜你喜欢
- 2025-06-08 这些不可不知的JVM知识,我都用思维导图整理好了
- 2025-06-08 Tomcat调优实战手册,从线程池到内存管理的性能突围战
- 2025-06-08 Java GC调优实战:从高频Minor GC到系统吞吐翻倍的破局之道
- 2025-06-08 Java 经典垃圾回收器详解(java垃圾回收器基本原理)
- 2025-06-08 面试Java被问JVM:你来详细聊一下G1垃圾收集器
- 2025-06-08 JVM调优实战:G1垃圾回收器如何让百万级系统告别卡顿
- 2025-06-08 GC优化实战:CMS vs G1(g1比cms高效的原因)
- 2025-06-08 JVM-G1垃圾收集器原理深入解析(jvm垃圾回收器详解)
- 2025-06-08 Java与Scala的Spark内存管理,当高效撞上安全,谁在主宰你的内存
- 2025-06-08 升级JDK17的理由,核心是降低GC时间
- 最近发表
-
- 一课译词:一刀两断(一刀两断成语解释)
- 核心短语break up用法解析(breakd短语)
- HTML+CSS 实现商品图片列表放大视觉效果 复制完整代码即可马上调用
- 前端实现右键自定义菜单(前端实现右键自定义菜单怎么设置)
- Python中docx与docxcompose批量合并多个Word文档并添加分页符
- Java 将Excel转为XML(java将xls转换成xlsx)
- jq+ajax+bootstrap改了一个动态分页的表格
- css兼容性问题及一些常见问题汇总大全,赶快收藏!
- Java 的业务逻辑验证框架 之-fluent-validator
- 小程序cover-view踩坑系列2(微信小程序overflow)
- 标签列表
-
- location.href (44)
- document.ready (36)
- git checkout -b (34)
- 跃点数 (35)
- 阿里云镜像地址 (33)
- qt qmessagebox (36)
- mybatis plus page (35)
- vue @scroll (38)
- 堆栈区别 (33)
- 什么是容器 (33)
- sha1 md5 (33)
- navicat导出数据 (34)
- 阿里云acp考试 (33)
- 阿里云 nacos (34)
- redhat官网下载镜像 (36)
- srs服务器 (33)
- pico开发者 (33)
- https的端口号 (34)
- vscode更改主题 (35)
- 阿里云资源池 (34)
- os.path.join (33)
- redis aof rdb 区别 (33)
- 302跳转 (33)
- http method (35)
- js array splice (33)