G1 GC最佳实践

JVM性能分析 —— G1 日志分析 文章目录日志级别-XX:+PrintGC(简洁版)-XX:+PrintGCDetails(详细版)-XX:G1LogLevel=finest(非常详细版)YGC 日志并发标记日志Mixed GC 日志Full GC 日志 日志级别 JVM 日志级别中的 fine、finer 和 finest 这三个级别 fine:JVM 配置参数为 -XX:G1LogLevel=fine 或使用 -XX:+PrintGC。 用于输出一些常规性的信息,不会产生太多的日志输出。 finer:JVM 配置参数为 -XX: 阅读详情

目录

  1. G1 GC 定义与原理概述
  2. G1 GC 的运行机制(Region、分代、并发、混合回收)
  3. 目标与设计哲学
  4. 关键 JVM 参数详解(用途、默认值、实践建议)
  5. 生产级最佳实践建议
  6. 日志分析与可观测性
  7. 容器(K8s)环境下最佳实践
  8. CMS 、G1、ZGC 对比
  9. 文档链接

1. 定义与背景

G1 (Garbage-First) 是 Java 9+ 的默认服务器端垃圾回收器(Java 11、17、21 都默认用 G1),设计目标是:

在大堆内存中获得低且可预测的停顿时间。

  • 前身:CMS(并发标记清理,Stop-the-World 压缩不并发,碎片多)

  • G1 解决的问题:

    • 碎片管理

    • 并发压缩

    • 停顿可预测性

📖 官方定义:

The Garbage-First (G1) garbage collector is a server-style collector for multiprocessor machines with large memories that meets garbage collection pause-time goals with high probability, while achieving high throughput.
→ OpenJDK G1 GC官方介绍


2. G1 GC 的运行机制

G1 的核心设计理念是分Region管理堆:

  • 整个堆被划分为固定大小的 Region(1MB~32MB,默认自动选)

  • 每个 Region 可动态标记为:Eden、Survivor、Old、Humongous


📌 年轻代收集

  • 和传统分代类似,Eden → Survivor → Old

  • 只回收 Eden 和 Survivor

  • Stop-The-World,但多线程并行


📌 并发标记周期

  • 并发标记所有存活对象

  • 计算每个 Region 的回收价值(Garbage-First)


📌 Mixed GC

  • 关键特性:

    • 在Young GC后,同时回收部分Old Region

    • 并发标记后触发

    • 优先“性价比高”的 Region


📌 Humongous Objects

  • 超过 Region 大小一半的大对象,直接分配到 Humongous Region

  • 可能产生碎片


📌 并发压缩

  • 老年代也会整理碎片

  • CMS 的缺点在于不能并发压缩,G1 可以


✅ 参考官方图示(Oracle 官方 GC Guide):
📖 G1 GC Overview - Oracle Docs


3. G1 GC 的设计哲学

参数驱动 = 以暂停时间为目标

  • -XX:MaxGCPauseMillis=N

    • G1 的核心指导参数

    • 告诉GC团队 “尽量把单次停顿时间控制在N ms以下”

⚠️ 但不是严格保证

  • G1 会动态调整

    • 年轻代大小

    • Mixed GC 步长

    • 并发标记启动阈值


4. 主要JVM参数详解

🎯 堆大小

  • 建议固定

-Xms8g -Xmx8g

避免扩容引起Full GC。


🎯 Region Size

  • 自动估算

-XX:G1HeapRegionSize=8m

可以手工指定(1MB ~ 32MB),但通常不用。


🎯 停顿时间目标

-XX:MaxGCPauseMillis=200

  • G1 会努力在200ms内完成回收。

  • 默认200ms,可根据业务要求调整:

    • 100~500ms常见。


🎯 并发标记启动阈值

-XX:InitiatingHeapOccupancyPercent=45

  • 触发并发标记的老年代占用比例

  • 降低值 → 提前并发标记 → 更稳定

  • 适用于老年代膨胀场景


🎯 并行/并发GC线程

-XX:ParallelGCThreads=8 -XX:ConcGCThreads=4

  • ParallelGCThreads → Stop-The-World 阶段并行线程数

  • ConcGCThreads → 并发标记阶段线程数

建议:

  • ParallelGCThreads ≈ CPU核数-2

  • ConcGCThreads ≈ ParallelGCThreads/2


🎯 并行引用处理

-XX:+ParallelRefProcEnabled

  • 并行处理软/弱/虚引用

  • 大对象回收时能显著减少停顿


🎯 预分配堆页面

-XX:+AlwaysPreTouch

  • 启动时预分配所有堆内存页

  • 避免运行时Page Fault

  • 建议在生产中开启


堆大小自动感知容器限制(容器)

✅ 参数:

-XX:+UseContainerSupport

✅ 说明:

  • Java 10+ / 11+ 默认开启

  • 让JVM自动读取cgroups限制

  • 没有这个参数,JVM在容器里会当作是「宿主机内存」来估算默认堆 → 可能太大 → OOMKilled


堆大小比例控制(容器)

✅ 重要参数:

-XX:MaxRAMPercentage

-XX:InitialRAMPercentage

✅ 作用:

  • 控制在容器内存限制(cgroups limit)的百分比

  • 替代传统的 -Xmx、-Xms 硬编码

✅ 示例:

-XX:MaxRAMPercentage=75 -XX:InitialRAMPercentage=75

  • JVM看到容器限制是 2GB → Max Heap ≈ 1.5GB

✅ 官方推荐(Oracle/OpenJDK):

  • 默认 MaxRAMPercentage=25(有点保守)

  • 实际生产常用:50–75%


✅ 官方参数手册:
📖 Java 17 GC Tuning Guide
📖 G1 GC Tuning Options - Oracle


 5. 生产级最佳实践参数推荐


✅ 推荐生产配置

-Xms8g -Xmx8g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=45 -XX:+AlwaysPreTouch -XX:+ParallelRefProcEnabled -Xlog:gc*:file=/path/to/gc.log:time,uptime,tags


✅ 容器环境(Kubernetes)

-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -XX:InitialRAMPercentage=75.0 -XX:+AlwaysPreTouch -XX:+HeapDumpOnOutOfMemoryError -XX:+ExitOnOutOfMemoryError

  • 避免 OOMKilled

  • 支持 cgroups 限制

📖 官方文档:
✅ Java in Containers - Oracle Guide


6. GC 日志分析与监控

  • 建议开启统一日志格式

-Xlog:gc*:file=/path/to/gc.log:time,uptime,tags

  • 重点指标:

    • Total GC Time

    • Pause Times

    • Mixed vs Young GC Ratio

    • Humongous Allocations

    • OldGen Usage

    • IHOP 变化

  • 工具推荐:

    • GCViewer (开源)

    • GCEasy.io

    • Java Flight Recorder (JFR)

    • Grafana + Prometheus JMX Exporter

📖 官方日志格式说明:
✅ Java 17 Logging Command-Line Options


7. 容器 / K8s 环境最佳实践

✅ JVM 参数

-XX:+UseContainerSupport -XX:MaxRAMPercentage=75 -XX:InitialRAMPercentage=75

✅ GC 日志

-Xlog:gc*:file=/mnt/logs/gc.log

✅ AlwaysPreTouch

  • 避免K8s热迁移或资源伸缩产生 page fault

✅ 建议分配

  • 容器限制 ≈ Xmx / 0.75

  • 给OS预留内存

8. CMS、G1、ZGC对比

特性CMSG1ZGC
堆布局分代(Young/Old)Region(动态标签)Region+染色指针(Load barriers)
老年代回收并发标记清理并发标记+并发压缩并发标记+并发重映射
碎片整理Stop-the-world 压缩并发+增量压缩并发、全程无Stop-the-world压缩
暂停特性低停顿,但 Full GC 影响大可预测暂停时间(默认200ms)极低停顿(通常<10ms)
并发标记是是是
并发整理否(压缩是STW)是是
Humongous对象支持普通分代逻辑特殊Region管理,易触发碎片支持超大对象分配
特性CMSG1ZGC
停顿可预测性差(碎片会恶化)✅ 可预测✅✅ 极好
并发能力并发标记,清理并发标记,增量压缩几乎全并发
碎片管理差,需Full GC压缩✅ 并发压缩✅✅ 并发重映射
复杂对象支持普通分配Humongous需特别关注✅ 超大对象也能并发回收
典型Full GC触发老年代碎片严重极少,除非堆完全爆满极少
生态支持Java 8 → 逐步淘汰Java 11+默认,企业首选Java 11+可选,Java 17/21成熟

9. 文档链接

✅ Oracle 官方 G1 GC 总入口  G1 GC in Java 17

✅ 参数和调优选项  G1 Tuning Options

✅ Java GC Tuning Guide(总览) Java SE 17 GC Tuning Guide

✅ Java in Containers(cgroups 支持)Java in Containers


结论

⭐ G1 GC 是 Java 11+ 的生产默认 GC
⭐ 最适合大堆、低停顿、SLA 有要求的微服务
⭐ 调优要围绕暂停时间目标(MaxGCPauseMillis)
⭐ 监控和日志分析是必须步骤
⭐ 容器化要考虑 cgroups 和堆参数

JVM原理及调优(6)——G1收集器及G1日志分析 系列文章规划: JVM基础(1)——内存模型 JVM基础(2)——内存管理 JVM基础(3)——编译机制 JVM基础(4)——类加载机制 JVM基础(5)——垃圾回收和调优 JVM基础(6)——G1收集器及G1日志分析 JVM基础(7)——jdk常用内置工具 1 G1简介 1.1 概述 G1 (Garbage-First)是一款面向服务器的垃圾收集器,主要针对配备多核处理器及大... 阅读详情

相关推荐

剖析G1(Garbage First)

欢迎关注笔者的公众号:【阿飞的博客】,首发都在这里!!! Java从JDK7U9开始支持G1(正式发布),所以,如果要使用G1的话,你的Java版本应该是JDK7U9或者更新的版本。不过,强烈建议JDK8才使用G1,而且最好是JDK8的最新版本,因为在JDK7~JDK8最新版本迭代过程中,Java针对G1垃圾回收期做了大量的优化工作。 G1垃圾回收器是为多处理器和大内存的服务器而设计的,它根据...

阿飞Javaer的专栏 1682

HotSpot JVM中关于G1GC介绍的官方文档地址

http://docs.oracle.com/javase/7/docs/technotes/guides/vm/G1.html Garbage-First Collector             Introduction The Garbage-First (G1) garbage collector is f

炎黄的专栏 4241

Fedproto:原型聚合的联邦学习框架

文中说明,联邦学习通过计算传递梯度聚合模型时,客户端之间的异构性通常会阻碍模型优化收敛和泛化性能。故本文提出新的FedProto框架,将梯度替换成为原型,通过计算、聚合从不同客户端收集到的本地原型,然后将全局原型发送回所有客户端,以规范本地模型的训练。对每个客户机进行局部训练的目的是最小化对本地数据的分类损失,同时保持生成的本地原型足够接近相应的全局原型(损失函数最小+正则)。什么是原型?文中提到:“

weixin_47754029的博客 2647

Java 17 启动参数字典

目前正常微服务综合内存占用+延迟+吞吐量,还是 G1 更优秀。但是如果你的微服务本身压力没到机器极限,要求延迟低,那么 ZGC 最好。如果你是实现数据库那样的需求(大量缓存对象,即长时间生存对象,老年代很大,并且还会可能分配大于区域的对象),那么必须使用 ZGC。使用 G1GC 启动参数: 使用 ZGC 启动参数: 其中,需要做成环境变量外部可以配置的是:JVM 日志配置请参考:OpenJDK 11 JVM日志相关参数解析与使用 - 知乎以下需要做成可以在外部配置的环境变量:除了以上内存,JVM 还

一瓶绿茶三元钱 2384

单片机OTA升级:Bootloader如何多重校验保障APP完整性?

本文详细介绍了单片机OTA升级中Bootloader如何通过CRC校验、数字签名、版本比对和存储位置检查等多重校验机制保障APP完整性。CRC校验作为快速检测数据完整性的核心手段,结合其他安全措施有效防止设备变砖和安全漏洞,确保远程升级的可靠性。

l3m4n的博客 981

基于STM32的Keil5代码自动补全设置操作指南

掌握Keil5代码自动补全设置技巧,提升STM32开发效率。通过合理配置编辑器选项,实现智能提示与语法补全,让嵌入式编程更流畅,尤其适合使用keil5代码自动补全设置的开发者快速上手。

weixin_32287387的博客 761

JVM调优汇总(JDK1.8)

JVM调优汇总 1、根据实际情况选择合适垃圾收集器 堆内存4G一下可以用parallel,4-8G可以用ParNew + CMS,8G以上可以用G1,几百级以上用ZGC。 2、jvm参数的初始值和最大值设置一样,避免扩容时消耗性能。 ‐Xms3072M ‐Xmx3072M ‐XX:MetaspaceSize=256M‐XX:MaxMetaspaceSize=256M 3、JVM调优目的:减少GC,主要是减少FullGC的频率。 优化思路: 尽可能让对象都在新生代里分配和回收,尽可能.

qq_36080515的博客 3605

新手必看!用FFmpeg一键合并ts文件的5种方法(含Windows/Mac终端命令)

本文详细介绍了使用FFmpeg合并TS视频文件的5种实用方法,涵盖Windows和Mac终端命令操作。从基础安装到进阶技巧,包括处理音频不同步、批量处理多个视频等场景,帮助用户轻松将m3u8分片视频合并为完整mp4文件,提升视频处理效率。

weixin_29065959的博客 554

JVM性能调优实战:G1垃圾收集器在大流量场景下的深度剖析

G1垃圾收集器在大流量生产场景下的调优,需要深入理解其Region划分、RSet维护、暂停时间预测等核心机制。Region大小选择:根据堆大小和对象分配模式,选择合适的Region大小,平衡RSet开销和回收灵活性暂停时间目标设置:根据业务SLA合理设置,避免过小值导致GC频率失控Mixed GC触发阈值调整:根据对象晋升速度调整,避免Full GC监控与诊断体系:建立完善的GC日志分析和JMX监控体系,及时发现和解决问题G1不是所有场景的最佳选择。

dicky_zhang3的博客 4618

STM32F4驱动ES8388音频芯片的I²S时钟与DMA流设计

I²S(Inter-IC Sound)是一种广泛应用于嵌入式音频系统的同步串行总线协议,其核心在于精确的时钟同步与稳定的数据流传输。理解I²S时钟树结构(含MCLK、SCLK、WS生成逻辑)和分频机制,是保障CD级音质(如44.1kHz/16bit)的基础;而DMA双缓冲技术则解决了实时音频播放中数据供给连续性的关键工程问题。在STM32F4等Cortex-M4平台中,需协同配置PLLI2S锁相环、I²S预分频寄存器(I2SxPR)及DMA循环模式,同时兼顾ES8388等Codec芯片的I²C初始化时序与寄

weixin_35390379的博客 244

G1垃圾收集器(六) 之 命令行选项和最佳实践

命令行选项和最佳实践 在这个章节,让我们一起看看G1的每个命令行选项。 基本的命令行选项 启用G1 GC,使用选项:-XX:+UseG1GC 这是一个最简单的命令行,来启动下载的JDK自带的demos和例子中的Java2Demo java -Xmx50m -Xms50m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar c:\javademos\dem...

z69183787的专栏 1458

RK3568下GPIO模拟串口

在嵌入式开发中,硬件 UART 资源可能被其他外设占用。此时,通过 GPIO 模拟 UART(软串口)成为一种灵活的解决方案。本文基于 RK3568 平台,结合 Linux 内核模块,实现高精度软串口通信,并深入分析关键技术细节。可以看到已经接收到数据了,可以自己创建自定义的设备文件到/dev下,也可以按照串口设备的标准创建一个设备,后面有时间我写一篇和标准串口设备结合的gpio模拟串口文章。RK3568 GPIO 模拟串口(软串口)实现详解。将编译好的驱动放到板子上运行。再写个Makefile。

文石_2009的博客 363

垃圾收集器CMS换G1

原则上G1会计算执行GC的时间,并且极力减少花在GC上的时间(包括ygc,mixgc),如果可能,会通过不断扩展堆空间来满足对象分配、转移的需要。G1的首要目标是为需要大量内存的系统提供一个保证GC低延迟的解决方案,也就是说堆内存最低在6GB及以上,稳定和可预测的暂停时间小于0.5秒。(2)G1在必要时也不能够增加或者缩小年轻代的空间. 因为大小是固定的,所以对更改大小无能为力;# 混合回收整理出来的空闲空间占heap的10时,结果老年代的回收,默认5。(1)Full GC 次数太频繁或者消耗时间太长;

杜引强 686

[实践篇]13.13 再来梳理一下HAB的设计原理

HAB全称为Hypervisor Abstraction,即硬件抽象,主要用于提供对HOST OS硬件资源的访问。

从0到1,突破自己 7256

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

jvm g1最佳实践及日志查看

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33905756的博客 1150

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

G1垃圾收集器入门

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34413357的博客 104

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

G1 GC调优实战:Full GC频率从每小时10次降到0次,我是怎么做到的?

还记得第一次遇到线上Full GC频繁,用户反馈系统卡顿,领导一句话:"你G1 GC参数调了吗?G1 GC调优不是一蹴而就的,需要理解原理、合理配置、持续监控、及时优化。用得好,能让你的Java程序在高并发、大数据量场景下依然稳健,Full GC频率降到最低。某电商系统,日活100万,QPS 5000,堆内存8G,Full GC每小时10次,用户反馈系统卡顿。:收集部分老年代Region,避免Full GC。:同时收集新生代和老年代,避免Full GC。,导致老年代持续增长,触发Full GC。

我爱娃哈哈的专栏 1178

理解G1垃圾收集器

一、G1简介 G1是jdk7推出的垃圾收集器,是jdk9之后的默认收集器,相当先进。相比大家所熟知的垃圾收集器例如serial,serial old,parnew,parallel scanvenge,parrallel odl,cms,G1有如下特点: 并行与并发 serial old与parrallel old在收集老年代时,在gc工作过程中需要STW(stop the world),执行并发标记,这个阶段往往是很耗时的,而G1可以在这个环节让gc线程与用户线程并行,这个特点类似CMS,但是两者的实现却

wanghang96的博客 2926

《GC算法通透理解:标记清除、复制、CMS与G1机制对比》

本文深入解析了Java垃圾回收(GC)算法的核心原理与实战应用。首先介绍了GC目标和分类,包括Minor GC/Major GC/Full GC的行为特征。重点剖析了标记清除、复制、标记整理三类基础算法及三色标记理论,详细对比了CMS和G1两大主流GC机制:CMS采用标记清除实现低延迟但存在碎片问题,G1通过分区Region和停顿预测模型实现可控延迟。文章提供了GC选择指南,推荐小堆用CMS、大堆用G1,并给出日志配置和调优建议,帮助开发者根据业务场景选择最优GC策略,平衡吞吐量、延迟和内存占用。

qq_43414012的博客 1475

G1垃圾收集器

文介绍如何使用G1,及在 Hotspot JVM 中怎么使用G1垃圾收集器。 您将了解 G1 收集器的内部原理, 切换为 G1 收集器的命令行参数, 以及让其记录GC日志的选项。 需要的时间 大约 1 个小时 简介 本文涵盖了Java虚拟机(JVM, Java Virtual Machine)中 G1 的基础知识。 第一部分, 简单概述JVM的同时介绍了垃圾收集和性能

yongfeng596的专栏 1060

Java 性能 02 - G1 收集器停顿时间优化(-XX:MaxGCPauseMillis)

本文深入探讨了G1垃圾收集器在Java性能优化中的关键作用,重点解析了-XX:MaxGCPauseMillis参数如何帮助开发者控制GC停顿时间。文章首先对比了传统GC的局限性,指出G1基于Region的设计和增量式回收策略如何实现更可控的停顿。通过测试订单处理系统的示例代码,展示了不同参数设置对GC行为的影响,并提供了调优建议:建议值200ms左右,需配合监控工具动态调整,同时注意与其他参数(如堆大小、并发线程数)的协同优化。文章强调,合理的GC调优能显著提升高并发场景下的系统响应性能,但需结合具体业务需

千淘万漉虽辛苦,吹尽狂沙始到金 2万+

SATB的标记问题解决之道与G1垃圾收集模式系统详解及最佳实践

继续接着上一次https://www.cnblogs.com/webor2006/p/11148282.html的理论学习,上一次学习到了这: 接着继续: SATB详解: 对于三色算法在concurrent的时候可能产生的漏标记问题,SATB在marking阶段中,对于从gray对象移除的目标引用对象标记为gray,对于black引用的新产生的对象标记为blcak;由于是在开始的时候进行sn...

webor2006的博客 293

深入理解JVM 垃圾收集器(下)G1收集器

1.回顾CMS 1.1堆内存结构 新生代分为Eden区和两个survivor区。老年代是一块连续区域。 只有FullGC时才可能发生内存整理。 1.2新生代GC 新生代淡绿色,老年代蓝色。系统运行一段时间后CMS堆内存可能如下图所示,对象分散在老年代各处。 新生代存活对象从Eden区和survivor区复制到另一个空闲的survivor区。任何minorGC年龄达到阈值的老对象被升级至老年代。 youngGC(minorGC)后,Eden区和一个survivor区...

314
上一篇: SpringBoot MVC配置:WebMvcConfigurer、WebMvcConfigurationSupport、WebMvcConfigurerAdapter
下一篇: Metric 指标类型及实践
fire-flyer
博客等级 码龄14年 218粉丝 51原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fire-flyer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值