关闭

Garbage First(G1)垃圾收集器

标签: JavaGarbage FirstG1垃圾算法
972人阅读 评论(0) 收藏 举报

引言:G1垃圾收集器采用一个略微不同的手段来解决并行、串行以及CMS GC的众多缺陷。对于大的Java堆来说,通过将Java堆拆分成一个个分区,G1会比其他垃圾收集器有更好的综合表现。
本文选自《Java性能调优指南》。

  G1垃圾收集器采用一个略微不同的手段来解决并行、串行以及CMS GC的众多缺陷。G1将堆拆成一系列的分区,这样在一个时间段内,大部分的垃圾收集操作就只是在一个分区内执行,而不是整个堆或整个(老年)代。

  在G1里,年轻代就是一系列的内存分区,这意味着不用再要求年轻代是一个连续的内存块。类似地,老年代同样也是由一系列的分区组成。这样也就不需要在JVM运行时考虑哪些分区是老年代,哪些是年轻代。事实上,G1通常的运行状态是映射G1分区的虚拟内存随着时间的推移在不同的代之间前后切换。一个G1分区最初被指定为年轻代,经过一次年轻代的回收之后,整个年轻代分区都被划入到未被使用的分区中,那它也就可以被使用在别的地方了。

  一个可用分区能被用于或指定为年轻代或老年代分区。很可能在完成一个年轻代收集之后,一个年轻代的分区在未来的某个时刻被用于老年代分区。同样地,在一个老年代分区完成收集之后,它就成为了可用分区,在未来某个时候作为一个年轻代分区来使用。

  G1年轻代的收集方式是并行stop-the-world。在垃圾收集线程执行过程中,并行stop-the-world回收将暂停所有Java应用线程,而垃圾回收的工作也将通过多个线程来分担。与其他HotSpot垃圾收集器一样,一旦发生一次年轻代垃圾收集,整个年轻代都会被回收。

  而G1老年代的垃圾收集方式与其他HotSpot垃圾收集器有着极大的不同。G1老年代的收集不会为了释放老年代的空间就要求对整个老年代做回收。相反,在任一时刻只有一部分老年代分区会被回收,并且,这部分老年代分区将与一次年轻代收集一起被收集。

贴士
术语混合(mixed)垃圾收集就是用来描述这种一部分老年代分区与年轻代收集结合在一起进行的收集。因此,混合GC就是在一次垃圾收集事件中,所有年轻代分区以及一部分老年代分区将会被回收。换句话说,混合GC就是将要被回收的年轻代与年老代分区的组合。

  与CMS GC类似,当遇到一些极端情况时,诸如老年代空间被消耗完了,会有一个安全措施来收集和压缩整个老年代。

  撇开安全模式下的收集不谈,一个G1老年代收集是由一系列阶段组成,某些是并行stop-the-world的,某些是并行并发的。也就是说,某些阶段是多线程的同时会暂停所有应用线程,而其他阶段是多线程的,但可以与应用线程同时运行。

  当超过Java堆的占用阈值,G1就会启动一次老年代收集。要注意到有一点非常重要,那就是G1中的堆占用阈值,这是根据老年代占用空间与整个Java堆空间相比较得出的。熟悉CMS GC的读者会记得,CMS触发老年代收集所用的占用阈值只是相对于老年代空间本身而言的。在G1中,一旦达到或超过内存堆的占用阈值,一次并发stop-the-world方式的初始标记阶段就会被安排执行。

  初始标记阶段会跟着下一次年轻代收集同时进行。一旦初始标记阶段结束,就会触发一个并发多线程的标记阶段,标记老年代中所有的存活对象。当并发标记阶段结束,并行stop-the-world的重新标记阶段就被启动,标记那些因为在标记阶段同时执行的应用线程导致产生错过的对象。到重新标记阶段结束,G1就拥有了老年代分区的完整信息。如果碰巧老年代分区里一个存活对象都没有,那么在下一个阶段——清除阶段,不用做额外的垃圾收集工作就可以被回收再利用。

  同样也是在重新标记阶段结束,G1能识别出最适合回收的老年代分区集合。

贴士 
在垃圾收集过程中收集的分区集合可以称为收集集合(CSet)。

  选择哪些分区被包含在一个CSet里,是基于有多少空间可以被释放以及G1暂停时间目标。在完成CSet识别之后,G1就在接下来的几次年轻代垃圾收集过程中对CSet中的分区进行回收。也就是说,在接下来的几个年轻代垃圾收集中,除了年轻代分区,还有一部分的老年代分区也将被回收。这就是前面提到的垃圾收集事件中的混合GC类型。

  不管是年轻代还是老年代,G1会把每个收集过垃圾的分区中的存活对象转移到一个可用分区中。一旦存活对象被转移掉,那这个年轻代分区(可能还有老年代分区)就会被回收为可用分区。

  将各老年代分区中的存活对象转移到可用分区会带来一个很有吸引力的结果——在虚拟地址空间里每个转移对象都是前后相连的,对象和对象之间没有碎片化的空余空间。我们回忆一下,CMS、并行以及串行垃圾收集器都需要一个full GC来压缩老年代,而这个压缩动作需要扫描整个老年代空间。

  因为G1以每个分区为基础做垃圾收集操作,所以它适用于大尺寸的Java堆。垃圾收集工作的数量可以被限制在一个小范围的分区集合内,哪怕Java堆尺寸可能会相当大。

  G1暂停时间的最大来源是年轻代收集和混合收集,所以G1的设计目标之一就是允许用户设置GC暂停时间目标。G1会尝试通过调整Java堆尺寸大小的方式来满足设定的暂停时间目标。它会根据暂停时间目标自动调整年轻代的尺寸和总的Java堆尺寸。暂停时间目标越短,年轻代空间就越小,总的堆空间就越大,使得老年代空间相对就越大。

  G1的设计目标就是把必要的调整限定在设置最大的Java堆空间和指定GC暂停时间目标上。另外,G1还被设计成可以通过一个内部的启发式算法来做自我调整。在写这本书的时候,G1的启发式算法就是HotSpot GC开发活动开展的最活跃的地方。同样到写这本书时为止,G1也许会要求一些特定场景下的额外调优,不过开发优秀的启发式算法的先决条件已经具备并且前景很可观。至于如何对G1进行调优的建议。

  综上,对于大的Java堆来说,通过将Java堆拆分成一个个分区,G1会比其他垃圾收集器有更好的综合表现。在局部压缩的帮助下,G1解决了Java堆碎片,它的绝大部分工作都通过多线程的方式完成。

  截止到写这本文时,G1首要针对的是那些有合理短暂停的大尺寸Java堆的用例,当然还有那些正在使用CMS垃圾收集器的应用。也有计划用G1来处理吞吐量用例,但对于那些追求高吞吐量,同时能容忍更长GC暂停的应用来说,目前并行垃圾收集器是更好的选择。

  本文选自《Java性能调优指南》,点此链接可在博文视点官网查看此书。
                    图片描述
  想及时获得更多精彩文章,可在微信中搜索“博文视点”或者扫描下方二维码并关注。
                       图片描述

1
0
查看评论

详解 JVM Garbage First(G1) 垃圾收集器

版权声明:本文为博主原创文章,转载请联系作者并注明出处。 详解 JVM Garbage First(G1) 垃圾收集器 前言 Garbage First(G1)是垃圾收集领域的最新成果,同时也是HotSpot在JVM上力推的垃圾收集器,并赋予取代CMS的使命。如果使用Java 8/...
  • coderlius
  • coderlius
  • 2018-02-06 17:25
  • 59

JVM 内存模型和垃圾回收(五): Garbage-First

JVM 内存模型和垃圾回收(五): Garbage-FirstG1回收是一个服务端的回收方式,适用于多个cpu和内存比较大的服务器使用。在6GB之下的内存下,CMS性能会更好,在6GB之上,G1的性能更好。并且在官方宣称G1是用来未来替换CMS的。和CMS不同的一点是: G1是将内存分为相等的区域,...
  • kang389110772
  • kang389110772
  • 2017-05-22 15:42
  • 236

【JVM】G1垃圾收集器的关键技术

前言G1 GC,全称Garbage-First Garbage Collector,通过-XX:+UseG1GC参数来启用,作为体验版随着JDK 6u14版本面世,在JDK 7u4版本发行时被正式推出,相信熟悉JVM的同学们都不会对它感到陌生。在JDK 9中,G1被提议设置为默认垃圾收集器(JEP ...
  • baiye_xing
  • baiye_xing
  • 2017-06-26 18:33
  • 1048

深入理解G1垃圾收集器

Garbage First(G1)致力于在多CPU和大内存服务器上对垃圾收集提供软实时目标(soft real-time goal )和高吞吐量(high throughput )。从JDK 6u14开始就已经在Hotspot上试验,到现在的JDK7依然没有走出实验室。是最终将用于代替Concurr...
  • joeyon
  • joeyon
  • 2016-08-25 16:48
  • 784

深入理解 Java G1 垃圾收集器

本文首先简单介绍了垃圾收集的常见方式,然后再分析了G1收集器的收集原理,相比其他垃圾收集器的优势,最后给出了一些调优实践。 一,什么是垃圾回收 首先,在了解G1之前,我们需要清楚的知道,垃圾回收是什么?简单的说垃圾回收就是回收内存中不再使用的对象。 垃圾回收的基本步骤 回收的...
  • lc0817
  • lc0817
  • 2016-12-25 09:59
  • 727

理解G1垃圾收集器日志

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

G1 垃圾收集器入门

G1 垃圾收集器 CMS垃圾收集器
  • zhanggang807
  • zhanggang807
  • 2015-05-26 16:53
  • 2357

Garbage First(G1)介绍

介绍: Garbage First(G1)致力于在多CPU和大内存服务器上对垃圾收集提供软实时目标(soft real-time goal )和高吞吐量(high throughput )。从JDK 6u14开始就已经在Hotspot上试验,到现在的DK7依然没有走出实验室: #java -vers...
  • libing13810124573
  • libing13810124573
  • 2014-03-20 00:10
  • 393

elasticsearch G1垃圾回收器

转载自:http://donlianli.iteye.com/blog/1948787 Java的垃圾回收真是让人又恨又爱。当今大内存已经成为服务器的趋势,使用CMS垃圾回收有点捉襟见肘。为何要使用g1垃圾回收,我想用过es的人都会很清楚。下面我就介绍一下在elasticsearch中,如...
  • BrotherDong90
  • BrotherDong90
  • 2015-07-13 17:07
  • 674

G1垃圾回收器--未完待续

堆空间被分割成大约2048个区域。region大小是2的次幂,最小1M,最大不超过32M,它的大小是在jvm初始化的时候就计算出来了,一旦计算出来以后就固定不变了,这个值jdk1.7与jdk1.8中的算法是不一样的;
  • zqz_zqz
  • zqz_zqz
  • 2017-10-10 16:06
  • 233
    个人资料
    • 访问:3927586次
    • 积分:56529
    • 等级:
    • 排名:第57名
    • 原创:1462篇
    • 转载:83篇
    • 译文:1篇
    • 评论:3786条
    博客专栏
    文章存档
    最新评论