网站首页 > 教程文章 正文
引言
在针对大型服务器或者是因为gc时间过长而影响用户性能的时候,G1垃圾收集器是一个非常不错的选择,也是我个人认为执行效率最高、对于用户体验有着最大的提高的垃圾收集器,当然前提是JVM服务器内存够大,建议16G或者更大,否则还是推荐使用CMS+ParNew(Old)组合垃圾回收器比较合适。
什么是G1收集器,有什么特点
G1垃圾收集器全称是Garbage-First,意义为进行最有价值的垃圾回收(汉语言的优美此刻完美体现)。G1是面向服务器级的垃圾收集器,主要针对多CPU以及大容量内存的机器,具有高吞吐量以及低GC停顿时间。
G1垃圾收集器的堆划分和其他垃圾收集器不大一样,G1将java 堆划分为若干个大小相等的堆内存区域,后面称为region。JVM堆中最多可以存在2048个region,每个region的大小就是堆的内存空间除以region个数,当然可以通过配置 -XX:G1HeapRegionSize 参数对region大小进行手动指定,不过因为G1内部有非常多的堆空间优化机制,所以推荐使用默认配置,不建议修改。
G1收集器堆空间分区情况
G1除了有其他垃圾收集器包含的eden、survivor、old外,还有一个特殊的humongous区,专门用于存储大对象,以下是每个分区功能以及特点:
- Eden、Survivor:新生代空间,G1中新生代默认初始空间占比为5%,可以通过配置修改此初始值,不过因为G1内部会在新生代空间不足时,根据内部算法自动增加新生代内存空间,所以不建议修改初始值。JVM在运行过程中,会不断给新生代空间分配内存,最高不超过60%,可以通过 -XX:G1MaxNewSizePercent 参数进行调整。新生代中eden和survior的内存分配为8:1:1
- Humongous:G1大对象分配区,在G1中,大对象的判定规则为超过单个region区域内存的50%即为大对象,大对象不需要心如新生代,直接进入humongous区,避免了大对象经历多次gc,影响jvm整体gc性能,也避免了这种短期生存的大对象挤压老年代内存空间,避免full gc的提前发生。如果单个对象大小超过一个region区域内存限制,G1则会给此对象分配多个连续的region空间进行存储。full gc运行时,也会对humongous区域的对象进行gc回收
- Old:除了其分布在多个region空间的特点之外,和其他收集器老年代功能以及用法一致
G1垃圾收集过程
G1垃圾收集整体过程和CMS类似核心思想也是降低业务线程停顿时间,让业务线程和gc线程并行工作,提高用户体验,不过G1的具体实现上更为优秀(当然大内存和CPU资源是必不可少)
- 初始标记:此阶段和CMS初始标记一致,会标记GC Root根直接关联的对象,此时暂停除GC线程外的所有
- 并发标记:此阶段和CMS并发标记一致,会并发标记初始标记对象的关联对象,业务线程同时运行,并记录此时业务线程导致的对象引用更新
- 最终标记:此阶段和CMS并发标记一致,会修正并发标记阶段业务线程导致的对象引用更新,此时暂停除GC线程以外的线程
- 筛选回收:G1的回收算法使用的是复制算法,筛选回收的意思是G1会根据 其参数设置对region区域进行选择性回收,G1内部会分析每个region的回收价值以及回收所需时长,如果单个region的可回收对象大小不足15%(可配置),G1则不会回收此region区域。同时G1会根据region区域需要的回收时长以及JVM设置的GC停顿时间来合理地进行内存回收。例如用户设置的GC停顿时长为100ms,G1会根据后台维护的优先列表来计算在100ms内能回收的最大region数,回收时间过程的不会进行回收,如果region合计回收时间远小于100ms,G1也不会进行回收,而是会开辟新的region空间存放对象
G1优势
- 高性能且与支持并行:在多核CPU前提下,充分使用CPU资源,做到并发且并行地进行垃圾收集,极大地减少了 stop the world的时长
- 支持分代收集:G1收集器可以直接对整个JVM 堆进行管理,不像CMS、ParNew等收集器只能对老年代或者新生代进行垃圾清理
- 空间整合:G1收集器采用的是复制收集算法,效率高于CMS的标记回收算法
- 停顿时长可设置:G1根据自带的停顿预测算法,让用户线程的停顿时间尽可能借用JVM设置的停顿时间,极大的提升了用户体验
G1垃圾收集方式
- YoungGC: 对G1 Eden区内存回收的回收方式,不过G1并不是在Eden区一满就会触发Young GC,而是会计算当前Eden区如果执行young gc需要执行的时间是否接近 预测停顿时长(通过参数 -XX:MaxGCPauseMills 进行设置),如果接近则会执行young gc,如果远小于预测停顿时长,则会继续分配region给eden空间给新对象存放
- MixedGC:此回收方式会对新生代以及部分老年代以及大对象区进行回收,老年区的回收空间大小是根据G1的内部算法,结合jvm设置的预测停顿时间,将老年区价值高的垃圾对象优先进行回收,使用的是复制算法,会将标记的有用对象复制到其他region中,再对需要清除的region进行全量清除,当无剩余region空间作为复制算法的目标空间时,就会触发full gc
- FullGC: 此回收方式非常简单粗暴,即使用单线程对内存空间进行标记清理以及压缩处理
G1收集器参数设置
- -XX:+UseG1GC:G1开启参数
- -XX:ParallelGCThreads:并发标记GC线程数
- -XX:G1HeapRegionSize:指定region分区大小,必须是2的整数次幂,最大32m,默认算法会将jvm堆空间划分为2048个region
- -XX:MaxGCPauseMillis:预测GC最大暂停时长,此参数对于G1收集器非常关键,默认200毫秒,需要根据具体业务进行设置
- -XX:G1NewSizePercent:新生代初始内存占比(默认5%,不建议修改)
- -XX:G1MaxNewSizePercent:新生代最大空间占比(默认60%,根据实际业务调整)
- -XX:TargetSurvivorRatio:survivor触发转移对象至老年代的阈值(默认50%),当survivor分区内存空间超过此阈值,会将年龄相比最大的对象移入老年区,直至survivor空间所用内存低于阈值
- -XX:MaxTenuringThreshold:新生代区最大年龄阈值,对象年龄达到此阈值后对象移入老年代
- -XX:InitiatingHeapOccupancyPercent:老年代空间占整体堆空间比例超过此阈值时,会触发mixgc,默认为45%
- -XX:G1HeapWastePercent:mixgc释放内存空间阈值,当jvm执行mixed gc后,会不断地有未空闲的region块被释放,当释放的region总内存量占堆空间比例达到此阈值后,停止mixed gc,默认5%
- -XX:G1MixedGCLiveThresholdPercent:当进行gc时,会计算当前region不可回收对象占region空间比例,如果该比例高于此阈值,则不会回收,默认85%
- -XX:G1MixedGCCountTarget:因为G1为了提高用户体验,回收过程中的筛选回收会分多次进行,此参数用于这是筛选回收拆分执行次数,默认8次
G1收集器使用建议
其实所有的垃圾回收器的优化都是大同小异,都是需要防止minor gc的频繁触发以及防止新生代的短期存活对象进入老年代,而G1收集器优化的最重要的点就是 -XX:MaxGCPauseMillis 参数,通过此参数可以设置新生代垃圾回收频率,同时可以基于对业务的评估,设置此参数,防止survivor区对象超过50%而短期存活对象被迫进入老年代的问题
猜你喜欢
- 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 Java与Scala的Spark内存管理,当高效撞上安全,谁在主宰你的内存
- 2025-06-08 升级JDK17的理由,核心是降低GC时间
- 2025-06-08 每天100w次登录请求,配置4核8G如何jvm调优
- 最近发表
-
- 一课译词:一刀两断(一刀两断成语解释)
- 核心短语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)