当前位置: 首页 > news >正文

G1垃圾回收器介绍和线上实践

一、前言

Java语言相较于C++等语言,一个显著的特点是垃圾回收机制,允许程序员在编写程序时无需考虑内存管理,统一由底层的垃圾回收机器进行垃圾回收。但是垃圾回收器在回收垃圾时,会对应用线程造成停顿,影响应用的性能。

在Java应用调优中,核心的两个指标为:响应时间和吞吐量。

1.1 响应时间

响应时间指的是应用对请求的响应时间,如:

  • 一个桌面应用对时间的响应时间

  • 网站返回一个页面的时间

  • 数据库查询结果返回时间

对于专注于最小响应时间的应用,长时间停顿是无法接受的。

1.2 吞吐量

吞吐量专注于应用在一段时间的的最大工作量。如:

  • 给定时间内完成的事物数

  • 每小时批处理程序能够完成的任务

  • 每小时数据库可以完成的查询操作数

较长停顿时间在此情况下是可以接受的。比起低响应时间,吞吐量优先应用更看重一段时间内的表现。

1.3 总结

基于两个指标,可得出评估一个垃圾回收器在实际业务中关键的是:单次最大停掉时间和周期内的停顿次数。

注:本文介绍的G1主要是基于JDK8进行分析,在后续的JDK版本中,有较多优化,比如JDK10 退化后的Full GC支持多线程等。

二、G1垃圾回收器

Garbage-First(G1)收集器时一款服务端垃圾收集器,主要针对多处理器、大内存环境设计。在尽可能满足GC停顿时间目标的同时获取更高的吞吐量。在JDK7u4版本开始支持

2.1 基本介绍

2.1.1 设计目标

  • 像CMS那样做到并发GC,提高GC并行和并发表现

  • 没有内存碎片问题,内存整理过程不需要延长GC时间,不需要虚拟机停顿STW

  • 可预测的GC停顿时间

  • 更高的吞吐量

  • 在不增加堆内存大小下更好地利用堆内存

G1的远期目标时替代CMS+ParNew(自适应的、分代的、停顿-复制、标记-清理并发垃圾回收器)组合。

2.1.2 优点

与CMS相比,G1优点包括:

  • G1是内存整理虚拟机,G1通过对堆内存划分区域(region),分区管理,避免使用细粒度空闲列表来实现高效内存整理;

  • G1提供比CMS更加可预测的GC停顿时间,并允许用户设定停顿时间目标。

2.1.3 推荐应用场景

G1的设计初衷是为用户提供大内存、低GC停顿时间的应用解决方案。

如果应用正在使用CMS或ParallelOld且面临以下问题,推荐将应用迁移至G1

  • FullGC发生频繁或总时间过长

  • 对象分配率或对象升级至老年代的比例波动较大

  • 较长的垃圾收集或内存整理停顿(大于0.5至1秒)

注意:

  • 如果应用没有上述问题,可以不需要切换到G1。

  • 切换到G1不要求更新JDK版本。

2.2 实现概览

2.2.1 老式垃圾回收器

老式垃圾回收器(Serial,Parallel,CMS)统一将堆分成大小固定的三部分:新生代、老年代和永久代。整体划分类似如下图所示:

2.2.2 G1 内存划分

在G1垃圾回收器中,使用了不同的内存划分方法,其将内存划分为不同小的区域(region),每个区域在虚拟内存上是连续的。同时在实际使用中,每个区域会像老式垃圾回收器一样,标记该region为eden、survivor和old,但是某个区域不是固定属于区(eden等),其余依据实际使用动态地去调整。

G1收集器将堆均分成大小相同的区域,每个区域的大小为1M~32M之间,最大支持2048个区域,因此G1最大可支持的内存为64G。

可参考源码:

https://github.com/wu560130911/jdk/blob/jdk8-b119/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp#L139

  // Minimum region size; we won't go lower than that.   // We might want to decrease this in the future, to deal with small   // heaps a bit more efficiently.   static const size_t MIN_REGION_SIZE = 1024 * 1024;   // Maximum region size; we don't go higher than that. There's a good   // reason for having an upper bound. We don't want regions to get too   // large, otherwise cleanup's effectiveness would decrease as there   // will be fewer opportunities to find totally empty regions after   // marking.   static const size_t MAX_REGION_SIZE = 32 * 1024 * 1024;   // The automatic region size calculation will try to have around this   // many regions in the heap.   static const size_t TARGET_REGION_NUMBER = 2048;

在不同堆大小写的区域大小如表格:

堆大小region大小
heap < 4GB1M
4GB <= headp < 8GB2M
8GB <= headp < 16GB4M
16GB <= headp < 32GB8M
32GB <= headp < 64GB16M
heap = 64GB32M

2.2.3 回收概要

G1垃圾收集过程与CMS类似。G1在堆内存中并发地对所有对象进行标记,决定对象的可达性。经过全局标记,G1了解哪些区域几乎是空的,然后优先收集这些区域,这就是GarbageFirst的命名由来。

G1将垃圾收集和内存整理活动专注于那些几乎全是垃圾的区域,并建立停顿预测模型来决定每次GC时回收哪些区域,以满足用户设定的停顿时间。

对于区域的回收通过复制算法实现。在完成标记清理后,G1将这几个区域的存活对象复制到一个单独区域中,实现内存整理和空间释放。这一过程通过多线程并行进行来降低停顿时间,提高吞吐量。通过这样的方式,G1在每次GC过程中持续清理碎片,控制停顿时间满足用户要求。

这是过去虚拟机无法做到的,CMS不清理内存碎片(除非通过虚拟机参数设置,在每次或多次FullGC后进行整理),ParallelOld进行全堆整理,会导致较长的停顿时间。

G1不是实时垃圾收集器,它会尽量让停顿时间低于用户设置的停顿时间目标但不能保证一定如此。

G1根据历史垃圾收集监测数据来 预测每个区域的回收时间,然后根据用户设定的目标停顿时间决定每次GC时可以回收哪些区域。G1通过 这种方式建立比较精确的区域回收时间预测模型。

注意:G1有并发阶段(与应用线程并行,无停顿时间)和并行阶段(多线程,应用工作线程停顿)。FullGC仍是单线程,如果调优合适,可避免出现FullGC。

2.2.4 特殊内存占用

http://www.jsqmd.com/news/642965/

相关文章:

  • PAA聚丙烯酸修饰纳米金棒,PAA@AuNRs,葡聚糖修饰纳米金棒,Dextran@AuNRs,反应特点
  • Google Colab 交互式表格:让数据分析和探索更直观
  • 2026年口碑好的配料秤控制器稳定供货厂家推荐 - 品牌宣传支持者
  • 别再傻等!Florence2大模型在ComfyUI里加载慢?试试这个手动加载的‘作弊’技巧
  • 编程范式比较与应用
  • 【SCI仿真】一种改进的适应性步长PO MPPT方法,用于带有电池站的独立光伏系统附Simulink仿真
  • 006、Prompt 工程入门:从会提问到会设计,前端开发者真正该掌握的提示词能力
  • 大模型Skill入门基础教程(非常详细),收藏这一篇就够了!
  • 从零部署:华为Atlas 300I Duo推理卡在Ubuntu下的ComfyUI文生视频实战
  • 终极指南:goflyway安全机制详解——从认证授权到加密传输的完整保护方案
  • 育苗基质到底是什么?一文读懂现代农业育苗核心,附真实种植案例
  • 时间戳周索引的自动生成
  • CefFlashBrowser:如何在2026年继续完美运行经典Flash内容的终极方案
  • Python面试题
  • 如何高效使用八大网盘直链下载助手:专业用户的完整解决方案
  • 从理论到实践:利用Smith预估器解决网络控制系统中的双延迟问题(含Matlab/Simulink案例)
  • Java 微服务架构设计最佳实践:构建可扩展的分布式系统
  • SqlMapAPI避坑实录:解决BurpSuite插件连接超时/端口占用问题(8775端口详解)
  • EMC测试项目与整改案例
  • 优质育苗基质核心标准科普:选对基质,育苗事半功倍
  • PHP源码对声卡有依赖吗_音频硬件无关性说明【方法】
  • 百度网盘直链解析:三步实现免会员高速下载的完整方案
  • 终极Ceres Solver损失函数指南:如何构建鲁棒的非线性最小二乘问题
  • OpenHTMLtoPDF深度解析:企业级HTML转PDF架构设计与最佳实践
  • 华为OD机试 - 统计员工影响力分数(Java 新系统 200分)
  • gcd/lcm + 素数判断与筛法
  • 第9章 函数-9.7 函数嵌套
  • AndroRAT客户端架构揭秘:Java实现远程控制的终极指南
  • PyTorch梯度累积实战:突破显存限制的Batch Size优化技巧
  • Vivado里那个AXI协议转换器IP核到底怎么用?手把手教你连接Zynq PS和旧版AXI3外设