本文来自OPPO互联网技术团队,转载请注名作者。同时欢迎关注我们的公众号:OPPO_tech,与你分享OPPO前沿互联网技术及活动。本文不讨论 G1 底层数据结构与算法,从 G1 GC 行为上做简要介绍 G1 的过程

Garbage-First Garbage Collector 从官网的描述来看:

G1 is a generational, incremental, parallel, mostly concurrent, stop-the-world, and evacuating garbage collector which monitors pause-time goals in each of the stop-the-world pauses. Similar to other collectors, G1 splits the heap into (virtual) young and old generations. Space-reclamation efforts concentrate on the young generation where it is most efficient to do so, with occasional space-reclamation in the old generation.

从介绍可以加粗几个重点分代

并发

STW

在每个STW阶段关注暂停时间目标

回收主要集中在最有效的young generation, old generation则没这么频繁

在G1中,为了提升吞吐量,有一些操作永远是(STW) stop-the-world 的。其他的一些要长期的,如全局标记这种要全堆进行的操作与应用程序并发进行。为了让空间回收的 STW 尽可能减少,G1并行的分步的递增进行空间回收。G1通过追踪此前应用行为和垃圾回收停顿的信息来构建一个与开销有关的模型(Pause Prediction Model)。它使用这些信息停顿期间可做的工作。举个例子,G1首先回收最高效的区域(也即垃圾最满的区域,因此称为垃圾—优先)。

G1把堆分成了n个大小相同的region

E 是 eden region

S 是 survivor region

O 是 old region

H 是 humongous (老年代可以是 humongous,可以看出,他可以跨越多个连续regions。直接分配到老年代,防止反复拷贝移动)

Java 9 以后开启的参数

自从 Java9 后,引入的统一的日志,也就是 Xlog 参数。下面是建议的 GCLog 参数:

-Xlog:gc*:file=your.log:tags,time,uptime,level:filecount=5,filesize=100

G1 的 GC 阶段

我们明白,调优的基本步骤就是Measure 收集相关诊断信息 (例如收集详细的gclog,默认log level info 可以满足大部分情况)

Understand 理解发生了什么

Tune 调优

只有明白了GC内部发生了什么,才能针对性的对其进行调整。

下面通过一些正常的 GC log 来理解 GC 的三种方式 GC 做了什么。

Young Only Phase

先用张图来简单理解 Young GC 过程垃圾回收的过程就是 Allocated->eden; eden -> survivor; survivor -> survivor; survivor -> old;

可以看到,这里有 eden,survivor,old 还有个 free region。

橙色就是活着的对象

G1会把橙色对象拷贝到free region

当拷贝完毕,free region 就会晋升为 survivor region,以前的 eden 就被释放了

如果 Young gc 中,花费了大量的时间

正常来说,大部分在 Young 的对象都不会存活很长时间

如果不符合这个规则 (大部分在 Young 的对象都不会存活很长时间),你可能需要调整一下 Young 区域占比。来降低 Young 对象的拷贝时间。

-XX:G1NewSizePercent (默认:5) Young region 最小值

-XX:G1MaxNewSizePercent (默认: 60) Young region 最大值

Mixed gc PhaseMixed gc 会选取所有的 Young region + 收益高的若干个 Old region。

同样的,被回收的 region 就变回 free region 了

从上图可以了解到 Mixed gc 只能回收部分的老年代

G1 是如何选择要回收的 regions 的?

-XX:G1MaxNewSizePercent 与 Young 关联

-XX:MixedGCCountTarget 与 old 关联

-XX:MixedGCCountTarget默认是8,意味着要在8次以内回收完所有的 old region

换句话说,如果你有 800 个 old region, 那么一次 mixed gc 最大会回收 100 个 old region

G1 也可以被调整成不做这么多工作,也就是回收少点,浪费堆内存,导致更堆使用

-XX:G1MixedGCLiveThresholdPercent(默认:85)可能会提高堆使用率

-XX:G1HeapWastePercent (默认:5) 如果可回收低于这个值, 那么将不会启动Mixed gc

Full gc PhaseFull gc 是不应该发生的

先来看看 GC 周期

G1 有两个阶段,它会在这两个阶段往返,分别是 Young-only,Space Reclamation.Young-only 包含一系列逐渐填满 old gen 的 gc

Space Reclamation G1 会递进地回收 old gen 的空间,同时也处理 Young region

图是来自 oracle 上对 gc 周期的描述,实心圆都表示一次 GC 停顿蓝色 Young-only

黄色 标记过程的停顿

红色 Mixed gc 停顿

在几次gc后,old gen 的对象占有比超过了 InitiatingHeapOccupancyPercent,gc就会进入并发标记准备(concurrent mark)。G1 在每一次 Young 回收中都会查找活对象(有引用的对象)

G1 在 old region 并发查找活对象

叫 concurrent marking

可能花费很长时间

不会停止 Java 应用

G1 没有活对象的引用信息是不能进行垃圾回收的

Mixed gc 依赖 concurrent mark

回到 full gc,从上面简单分析得出,full gc 发生是没有足够的 free region,如果堆是足够大的,Mixed gc 没有回收足够的 old region,或者 concurrent mark 没法及时完成,都可能会导致 full gc。

gc 日志

[gc,start ] GC(78) Pause Young (Normal) (G1 Evacuation Pause)

上面是连续几次GC的日志,可以对照着 gc 周期来看。为了方便排版,把时间相关的tag给精简掉了。GC(78) 是一次普通的young gc,里面信息有各种 region 的变化

这里简单说一下 humongous 对象的处理

humongous 对象在G1中是被特殊对待的,G1 只决定它们是否生存,回收他们占用的空间,从不会移动它们

Young-Only 阶段,humongous regions 可能会被回收

Space-Reclamation,humongous regions 可能会被回收

GC(79) 开始进入并发阶段

GC(80) 完成了 Cleanup,紧接着一个 Prepare Mixed GC(81) 的垃圾收集,对应周期虚线右边的蓝实心圆

GC(82) 之后就是 Space Reclamation 阶段了,多个 Mixed GC 会进行

根据日志,可以简单看到每个步骤花费的时间,以及对应区域垃圾的回收情况,结合GC参数,可以定位出什么问题,针对性的调整参数。吞吐量跟低延时是无法兼得的,低延时意味着GC工作会更加频繁,相对的,会占用应用的资源,吞吐量降低。需要大吞吐量,那么GC工作就会减少,相对的,每次回收的垃圾就会多,暂停时间就会增加,延时就会增加。-XX:MaxGCPauseMillis G1 会尽量满足这个参数设定的目标时间,通过此参数可以平衡应用需要的吞吐量以及延时。

最后

本文主要参考资料是官方的文章和文档,没涉及到复杂的内部实现,新版的JDK除了对G1进行了改良之外,还推出了几种新的。Epsilon GC (no-op),无操作垃圾回收器,简单点就是不回收垃圾,等堆空间分配完了,jvm也就停止了

zgc 超大堆垃圾回收器,暂停不超过10ms,支持T级别的堆

Shenandoah 同样也是低延迟垃圾回收器

由于知识简陋,难免会有勘误,欢迎讨论。

参考资料

java中的g1_G1GC 概念与性能调优相关推荐

  1. 让 Java 应用运行更快:性能调优工具及实践

    Java 应用性能优化是一个老生常谈的话题,典型的性能问题如页面响应慢.接口超时,服务器负载高.并发数低,数据库频繁死锁等.尤其是在"糙快猛"的互联网开发模式大行其道的今天,随着系 ...

  2. java必读书籍_最佳5本Java性能调优书籍–精选,必读

    java必读书籍 为什么Java开发人员应该阅读有关性能调优的书? 当我很久以前第一次面对这个问题时,我以为以后会做,但是我很长一段时间都没有回过头来. 仅当我在用Java编写的任务关键型服务器端财务 ...

  3. 最佳5本Java性能调优书籍–精选,必读

    为什么Java开发人员应该阅读有关性能调优的书? 当我很久以前第一次面对这个问题时,我以为以后会做,但是我很长一段时间都没有回过头来. 仅当我在用Java编写的任务关键型服务器端财务应用程序中遇到严重 ...

  4. 看完去怼面试官,Java尊享版性能调优分享给大家

    很多程序员一开始在学习上找不到方向,但我想在渡过了一段时间的新手期之后这类问题大多都会变得不再那么明显,工作的方向也会逐渐变得清晰起来. 但是没过多久,能了解到的资料就开始超过每天学习的能力,像是买了 ...

  5. 深入理解JVM性能调优

    深入理解JVM性能调优 您的评价:        收藏该经验     width="728" height="90" frameborder="0&q ...

  6. 十八般武艺玩转GaussDB(DWS)性能调优(二):坏味道SQL识别

    摘要:那些会导致执行效率低下的SQL语句及其执行方式,我们称之为SQL中的"坏味道". ◆ 什么是SQL中的坏味道 SQL语言是关系型数据库(RDB)的标准语言,其作用是将使用者的 ...

  7. sql union 行数不同_十八般武艺玩转GaussDB(DWS)性能调优(二):坏味道SQL识别

    摘要:那些会导致执行效率低下的SQL语句及其执行方式,我们称之为SQL中的"坏味道". ◆ 什么是SQL中的坏味道 SQL语言是关系型数据库(RDB)的标准语言,其作用是将使用者的 ...

  8. java jvm调优_(第2部分,共3部分):有关性能调优,Java中的JVM,GC,Mechanical Sympathy等的文章和视频的摘要...

    java jvm调优 这是以前的文章(第3部分,共1部分)的继续:有关性能调优,Java中的JVM,GC,Mechanical Sympathy等的文章和视频的提要 . 事不宜迟,让我们开始使用我们的 ...

  9. java jvm调优_(第1部分,共3部分):有关性能调优,Java中的JVM,GC,Mechanical Sympathy等的文章和视频的摘要...

    java jvm调优 我已经花了几个月的时间考虑审查有关性能调优,JVM,Java中的GC,Mechanical Sympathy等主题的文章和视频的缓存,并最终花了点时间–也许这就是重点我什么时候才 ...

  10. (第1部分,共3部分):有关性能调优,Java中的JVM,GC,Mechanical Sympathy等的文章和视频的摘要...

    我已经花了几个月的时间考虑审查有关性能调优,JVM,Java中的GC,Mechanical Sympathy等主题的文章和视频的缓存,并最终花了点时间–也许这就是重点我什么时候需要做我的智力进步! 感 ...

最新文章

  1. AI人才抢夺“生猛”: 应届博士年薪涨到80万元
  2. wpf 控件大小随窗体大小改变而改变
  3. adc如何获取周期_LOL:千珏拥有ADC最需要的位移和无敌能力,为什么没人用她打下路?...
  4. echarts 图例太多放不下怎么办_如何选择合脚的篮球鞋?篮球鞋不合脚怎么办?...
  5. android sdk 官网说明,神目人脸识别Android SDK Demo说明
  6. C#.NET Split 的几种使用方法
  7. Linux操作系统 和 Windows操作系统 的区别
  8. 树莓派Python编程手册
  9. shell脚本中执行ssh
  10. APP爬虫|frida-某资讯app逆向过程,带你一起使用 frida 进行完整逆向
  11. 论文笔记:Multi-level Alignment Network for Domain Adaptive Cross-modal Retrieval
  12. 怎么用PHP抓取百度排名?
  13. Docker快速入门与使用
  14. 3d打印 计算机芯片,提高计算机芯片数据路由能力!3D打印最小龙勃透镜诞生
  15. PRE_LOAD+putenv
  16. android调用系统相机实现拍照功能
  17. STM32-Keil软件仿真和硬件仿真/在线仿真
  18. 分析CRM客户管理系统哪家做的好?
  19. 人体内数量最多的神经元,人体内有多少个神经元
  20. 玩csgo闪退怎么办?Win10玩csgo闪退的解决方法

热门文章

  1. 浙江大学计算机学院陈越教授,科学网—浙大教授陈越:快乐教学 行者无疆
  2. 《开学第一课》观后感——幸福
  3. 可通过qq聊天机器人拿下服务器权限
  4. 生成和获取法定节假日
  5. 随想录:开发一流Android SDK
  6. 安装MySQL8.0+,数据库初始化失败错误解决办法
  7. 关闭Software Reporter Tool
  8. C# 多线程造成CPU占用率高解决办法
  9. 一位10年 Java 工作经验的架构师聊 Java 和工作经验
  10. 32-【算法与数据结构】伪代码与流程图