关闭

我眼中的G1 GC

标签: javajvmG1GC
1576人阅读 评论(2) 收藏 举报

摘要: 本文作者周明耀,让我们回到1998年,随作者从GC发展史开始一同重新了解G1 GC。 相关图书推荐,《深入理解JVM & G1 GC》。

  7岁那年,当我合上《上下五千年》一套三册全书时,我对自己说,我想当个作家。这一晃27年了,等待了27年,我的第一本书《大话Java性能优化》在2016年4月正式面世,2016年8月第二次印刷,2017年5月第三次印刷,感谢读者的厚爱。《深入理解JVM&G1 GC》这本书是我的第二本书,也即将面世。对于我的每一本书,我都怀着忐忑、惊喜的心情,就像第一次面对我的女儿“小顽子”,给她取这个小名,希望她顽强到底,因为我相信,你若顽强到底,一切皆有可能。

  我喜欢看书,每年购买的书接近100本,也喜欢对技术进行积累。一直没有出书的想法,直到遇到了电子工业出版社的董老师,在深圳南湖的一席畅谈后,我决定做一位业余的技术作家,致力于中国软件开发行业的技术推广、普及、推动。

  这本书是介绍JVM和G1 GC的,让我们回忆一下。还记得哆啦A梦吗?他和大熊有一张书桌,书桌的抽屉其实是一个时空穿梭通道,现在让我们来掌控这个时空机器,回到1998年。那年的12月8日,第二代Java平台的企业版J2EE正式对外发布。为了配合企业级应用落地,1999年4月27日,Java程序的舞台—Java HotSpot Virtual Machine(以下简称HotSpot )正式对外发布,并从这之后发布的JDK1.3版本开始,HotSpot成为Sun JDK的默认虚拟机。
            图片描述

GC发展历史简介

  1999年随JDK1.3.1一起来的是串行方式的Serial GC ,它是第一款GC,并且这只是起点。此后,JDK1.4和J2SE1.3相继发布。2002年2月26日,J2SE1.4发布,Parallel GC 和Concurrent Mark Sweep (CMS)GC跟随JDK1.4.2一起发布,并且Parallel GC在JDK6之后成为HotSpot默认GC。

  HotSpot有这么多的垃圾回收器,那么如果有人问,Serial GC、Parallel GC、Concurrent Mark Sweep GC这三个GC有什么不同呢?请记住以下口令:

  • 如果你想要最小化地使用内存和并行开销,请选Serial GC;
  • 如果你想要最大化应用程序的吞吐量,请选Parallel GC;
  • 如果你想要最小化GC的中断或停顿时间,请选CMS GC。

那么问题来了,既然我们已经有了上面三个强大的GC,为什么还要发布Garbage First(G1)GC?原因就在于应用程序所应对的业务越来越庞大、复杂,用户越来越多,没有GC就不能保证应用程序正常进行,而经常造成STW的GC又跟不上实际的需求,所以才会不断地尝试对GC进行优化。

  为什么名字叫做Garbage First(G1)呢?

  因为G1是一个并行回收器,它把堆内存分割为很多不相关的区间(Region),每个区间可以属于老年代或者年轻代,并且每个年龄代区间可以是物理上不连续的。

 老年代区间这个设计理念本身是为了服务于并行后台线程,这些线程的主要工作是寻找未被引用的对象。而这样就会产生一种现象,即某些区间的垃圾(未被引用对象)多于其他的区间。

  垃圾回收时实则都是需要停下应用程序的,不然就没有办法防治应用程序的干扰 ,然后G1 GC可以集中精力在垃圾最多的区间上,并且只会费一点点时间就可以清空这些区间里的垃圾,腾出完全空闲的区间。

  绕来绕去终于明白了,由于这种方式的侧重点在于处理垃圾最多的区间,所以我们给G1一个名字:垃圾优先(Garbage First)。

G1 GC基本思想

  G1 GC是一个压缩收集器,它基于回收最大量的垃圾原理进行设计。G1 GC利用递增、并行、独占暂停这些属性,通过拷贝方式完成压缩目标。此外,它也借助并行、多阶段并行标记这些方式来帮助减少标记、重标记、清除暂停的停顿时间,让停顿时间最小化是它的设计目标之一。

  G1回收器是在JDK1.7中正式投入使用的全新的垃圾回收器,从长期目标来看,它是为了取代CMS 回收器。G1回收器拥有独特的垃圾回收策略,这和之前提到的回收器截然不同。从分代上看,G1依然属于分代型垃圾回收器,它会区分年轻代和老年代,年轻代依然有Eden区和Survivor区,但从堆的结构上看,它并不要求整个Eden区、年轻代或者老年代在物理上都是连续。

  综合来说,G1使用了全新的分区算法,其特点如下所示:

  1. 并行性:G1在回收期间,可以有多个GC线程同时工作,有效利用多核计算能力;
  2. 并发性:G1拥有与应用程序交替执行的能力,部分工作可以和应用程序同时执行,因此,一般来说,不会在整个回收阶段发生完全阻塞应用程序的情况;
  3. 分代GC:G1依然是一个分代收集器,但是和之前的各类回收器不同,它同时兼顾年轻代和老年代。对比其他回收器,或者工作在年轻代,或者工作在老年代;
  4. 空间整理:G1在回收过程中,会进行适当的对象移动,不像CMS只是简单地标记清理对象。在若干次GC后,CMS必须进行一次碎片整理。而G1不同,它每次回收都会有效地复制对象,减少空间碎片,进而提升内部循环速度。
  5. 可预见性:由于分区的原因,G1可以只选取部分区域进行内存回收,这样缩小了回收的范围,因此对于全局停顿情况的发生也能得到较好的控制。

随着G1 GC的出现,GC从传统的连续堆内存布局设计,逐渐走向不连续内存块,这是通过引入Region概念实现,也就是说,由一堆不连续的Region组成了堆内存。其实也不能说是不连续的,只是它从传统的物理连续逐渐改变为逻辑上的连续,这是通过Region的动态分配方式实现的,我们可以把一个Region分配给Eden、Survivor、老年代、大对象区间、空闲区间等的任意一个,而不是固定它的作用,因为越是固定,越是呆板。

G1 GC垃圾回收机制

  通过市场的力量,不断淘汰旧的行业,把有限的资源让给那些竞争力更强、利润率更高的企业。类似地,硅谷也在不断淘汰过时的人员,从全世界吸收新鲜血液。经过半个多世纪的发展,在硅谷地区便形成只有卓越才能生存的文化。本着这样的理念,GC承担了淘汰垃圾、保存优良资产的任务。

  G1 GC在回收暂停阶段会回收最大量的堆内区间(Region),这是它的设计目标,通过回收区间达到回收垃圾的目的。这里只有一个例外情况,这个例外发生在并行标记阶段的清除(Cleanup)步骤,如果G1 GC在清除步骤发现所有的区间都是由可回收垃圾组成的,那么它会立即回收这些区间,并且将这些区间插入到一个基于LinkedList实现的空闲区间队列里,以待后用。因此,释放这些区间并不需要等待下一个垃圾回收中断,它是实时执行的,即清除阶段起到了最后一道把控作用。这是G1 GC和之前的几代GC的一大差别。

  G1 GC的垃圾回收循环由四个主要类型组成:

  • 年轻代循环
  • 多步骤并行标记循环
  • 混合收集循环
  • Full GC

在年轻代回收期,G1 GC暂停应用程序线程,然后从年轻代区间移动存活对象到Survivor区间或者老年区间,也有可能是两个区间都会涉及。对于一个混合回收期,G1 GC从老年区间移动存活对象到空闲区间,这些空闲区间也就成为了老年代的一部分。

  技术方面介绍到这里,有兴趣的读者可以买一本看看。这本书主要为学习Java语言的学生、初级程序员提供JVM和GC的使用和优化建议及经验交流,力求做到知识的综合传播,而不是仅仅只针对Java虚拟机调优进行讲解。本书具体来说包括以下几方面:JVM基础知识、GC基础知识、G1 GC深入介绍、G1 GC调优建议、JDK自带工具使用介绍等。

  相关图书推荐,《深入理解JVM & G1 GC》。
                      图片描述
  想及时获得更多精彩文章,可在微信中搜索“博文视点”或者扫描下方二维码并关注。
                         图片描述

0
0
查看评论

GC(G1算法)

Java 8 默认的 GC是Parallel GC。Oracle正在考虑将JEP 248包含到Java 9的JEP列表中,即在服务器配置中将G1作为默认垃圾收集器。The Garbage-First (G1) garbage collector is fully supported in Oracl...
  • youyou1543724847
  • youyou1543724847
  • 2016-10-03 15:36
  • 1347

JVM基础(6)——G1收集器及G1日志分析

1. G1简介1.1 概述G1 (Garbage-First)是一款面向服务器的垃圾收集器,主要针对配备多核处理器及大容量内存的机器。 在极大概率满足GC停顿时间要求的同时,还具备高吞吐量的特性.。Oracle JDK 7 update 4 及以上版本已完全支持。其设计目标如下: 可以像CMS收集...
  • weitry
  • weitry
  • 2016-11-15 12:57
  • 2681

深入理解JVM 一GC(下) G1 Garbage Collector

关于java程序性能当我们调优java程序时,通常的目标有两个: 响应能力 或者 吞吐量响应能力响应能力指一个程序或者系统对请求的是否能够及时响应。 比如: 一个桌面UI能多快的响应一个事件; 一个网站能够多快返回一个页面请求; 数据库能够多快返回查询的数据;对于这类对响应能力敏感的场景,...
  • lemon89
  • lemon89
  • 2017-04-04 12:48
  • 2316

Serial,Parallel,CMS,G1四大GC收集器特点小结

1.Serial收集器 一个单线程的收集器,在进行垃圾收集时候,必须暂停其他所有的工作线程直到它收集结束。 特点:CPU利用率最高,停顿时间即用户等待时间比较长。 适用场景:小型应用 通过JVM参数-XX:+UseSerialGC可以使用串行垃圾回收器。 2.Parallel收集器 采用多线程来通...
  • u013812939
  • u013812939
  • 2015-09-28 11:39
  • 3480

理解G1垃圾收集器日志

理解G1垃圾收集器日志 发表这个文章的目的是为了解释使用了G1垃圾收集器的一些跟踪和诊断选项而生成出来的垃圾收集日志的意义。我们来看一下使用一个提供最详细的信息级别的生产环境选项PrintGCDetails生成的输出日志。同时,我们也会看一下启用的两个诊断选项 -XX:+UnlockDiagn...
  • zhanggang807
  • zhanggang807
  • 2015-05-27 16:57
  • 2537

HotSpot的G1收集器(日志分析)

GC日志分析         笔者找了一个WEB项目,然后使用如下GC参数,获得G1的GC日志。 -Xmx1024m -Xms1024m -XX:+UseG1GC -XX:+PrintGCDetails -XX:MaxGCPauseMillis=200...
  • wuxian90
  • wuxian90
  • 2017-10-28 15:21
  • 148

G1 GC日志分析

使用UseG1GC这个选项显示地要求JDK7或者JDK8对应的JVM采用G1 GC,据说JDK9开始默认GC会变更为G1 GC(现在是ParallelGC),但一切皆有可能。我们使用VM参数-XX:+PrintGCDetails-verbose:gc -Xloggc:gc.log -XX:+UseG...
  • zmycoco2
  • zmycoco2
  • 2017-09-20 20:04
  • 397

JDK7新特性之G1 GC

Garbage-first garbage collector,简称G1 GC,是最终将用于代替Concurrent Mark-Sweep garbage collector(CMS GC)的新一代垃圾回收器。原本的计划是作为JDK7新特性的一部分发布,但其后JDK7一直在坚持不懈的跳票,G1也无法...
  • novelly
  • novelly
  • 2014-02-11 10:04
  • 1317

GC之--G1 GC

Garbage-first garbage collector,简称G1 GC,是最终将用于代替Concurrent Mark-Sweep garbage collector(CMS GC)的新一代垃圾回收器。原本的计划是作为JDK7新特性的一部分发布,但其后JDK7一直在坚持不懈的跳票,G1也无法...
  • u011031854
  • u011031854
  • 2013-12-21 10:00
  • 1203

深入JVM之G1收集器

深入JVM之G1收集器一、G1收集器简介 G1收集器(JDK1.7u4正式出现) 普遍存在:全内存扫描问题。 传统的收集器不能满足高内存高cpu的要求,这才是G1产生的原因。 G1区域划分 在G1之中不再区分所谓的年轻代、老年代内存空间,所有的内存空间就是一块。但是要划分出不同的子区域。二、G1...
  • qq_34280276
  • qq_34280276
  • 2016-10-19 21:26
  • 3260
    个人资料
    • 访问:3923657次
    • 积分:56494
    • 等级:
    • 排名:第57名
    • 原创:1462篇
    • 转载:83篇
    • 译文:1篇
    • 评论:3786条
    博客专栏
    文章存档
    最新评论