Java新型垃圾回收器G1深入探索

开发 后端
JDK 7中新增的垃圾回收器G1是一个“服务器风格(server-style)”的垃圾回收器,本文向您介绍他的属性、状态和一些使用特性。

G1垃圾回收器

“G1垃圾回收”的英文全称是 Garbage-First Garbage Collector (又被称作G1 GC),这是一个新型的垃圾回收器,由JDK 7中的Java HotSpot VM 引入。这个技术曾经在Java SE 6 Update 14版本中出现过一个试验性的,然后 G1 被 HotSpot的 反应快速(low-latency)的 Concurrent Mark-Sweep GC (简称 CMS)长期取代。

属性

G1 是一个“服务器风格(server-style)”的垃圾回收器,它主要有下面的这些属性:

并行和并发。 G1 可以从今天最新的硬件中获得并行的能力。它能够使用所有可用的CPU(CPU多核,硬件多线程,等)来加速它的 “stop-the-world” 机制(这个机制简称STW,即,在执行垃圾收集算法时,Java应用程序的其他所有除了垃圾收集帮助器线程之外的线程都被挂起)。

分代处理。 就像其它的HotSpot 垃圾回收器,G1 是分代的,也就是说,它在处理新分配的对象(年轻代)和已经生存了一段时间的对象(年老代)时会不同,它会更多地考虑一些新创建的对象实例,因为越新创建的就越有最大的可能性被回收,老对象只是偶尔访问一下。对于大多数的Java应用来说,这个机制可以极大地提高回收效率。

紧凑内存(碎片整理)。 不像CMS,G1 会对堆进行内存整理。压缩可以消除潜在的内存碎片的问题,这样程序就可以更长时间的平滑运行。

预见性的。 G1 比起 CMS 来有更多的预见性。这个主要还是用来消除内存碎片的问题。内存的碎片少了,Stop-the-World的暂停时间也会被减少。

描述

比起其它的HotSpot 垃圾回收器来说,G1 使用了一种非常不同寻常的方法来管理堆内存的布局。在G1中,在对象新生代和老一代上没有在物理上把他们分隔开来。取而代之的是,它把一个连续的堆内存拆分成了几个相同大小的区域。新产生的对象和老的对象都会被放在一系列可能不会连续的区域中。之所以这样做,就是为了让G1可以更灵活地移动老对象所占用的资源给新的对象。

G1中的内存收集会发生 “疏散暂停”,当内存从一系例区域开始回收时,这些区域所引用的 collection set 会被疏散到另一些区域中,这样,我们会有一整块的内存来重新被申请。疏散会发生整个程序的暂停,但“疏散”这些内存可以被并行运行,当然,你要有多核或多线程技术来支持。绝大多数的“疏散暂停”会去收集那些可用的比较新的内存区域,因此,这和其它的 HotSpot 垃圾回收器是相同的。偶而才会去查看一下老区域中的内存是否可以回收。

在 CMS中,其周期性的执行一个 concurrent marking phase。 这个phase中最主要的事情是,识别哪些老的区域中充满了可以回收的对象,因为这是最有效率和最合适的回收。但在G1中,G1不会执行那个所谓的 concurrent sweeping phase, 取而代之的是,去识别那些的最合适的老的区域是在并发的“疏散暂停”中进行的(后面会做介绍)。

使用 G1

G1 目前仍然还在试验阶段,使用下面两个参数可以打开G1机制:

-XX:+UnlockExperimentalVMOptions -XX:+UseG1GC

下面是设置垃圾回收器的暂停时间:

-XX:MaxGCPauseMillis =50 (设置暂停时间为 50ms)

在G1中,你还可以给垃圾回收器的暂停设置一个时间间隔:

-XX:GCPauseIntervalMillis =200 (设置暂停时间间隔 200ms)

注意,上面的两个参数只是代表目标,回收器并不保证。他们可能在某些情况下工作地很好,也可能在其它情况下不行,所以,垃圾回收器并不总是服从这两个参数设置。

另外,新生代的内存大小可以被设置,这个参数同样会影响“疏散暂停”的时间:

-XX:+G1YoungGenSize=512m (设置新生代内存为 512兆字节)

G1 同样可以使用survivor 空间,是的,这就是多少个区域。大小可以由通用的参数所指定(如: -XX:SurvivorRatio=6).

最后,如果你要发挥G1的所有潜能,你可以尝试设置下面两个参数,它们默认上是关闭的,因为在一些很稀有的情况下,这两个参数会发生race condition(竞争条件):

-XX:+G1ParallelRSetUpdatingEnabled
-XX:+G1ParallelRSetScanningEnabled

还有一件事是G1能够报告比其它垃圾回收站更详细的信息,当然,你需要设置下面这个参数:

 -XX:+PrintGCDetails

这个参数会输出很多有用的信息供你查看性能与以 trouble-shooting。如果你想要简单的日志,你可以把这个开关设置到 -verbosegc 。

状态

◆G1 开发目前主要关注于解决一些残留的稳定性的问题,以及提高性能,并且去除下面的限制:

◆G1 并不完全支持 JVM Tool Interface (JVM TI) 或 Java Management Extensions (JMX),所以,这些监控和管理工具无法正确地作用于G1。

◆G1 不支持增量的永生代collection。如果一个应用在卸载很多的类,因些需要很多的永生代Collection,目前的G1还不支持,不过最终版会支持。
 
关于垃圾回收器的暂停时间,G1的表现比起CMS来说是时好时坏。所以,还有很多工作需要让G1的表现更加稳定,绝不能比CMS还差,不然G1还有什么意思呢?

 

【编辑推荐】

  1. 探秘Java 7新增垃圾回收器G1特性
  2. Java SE 6中的垃圾回收器G1收费是虚惊一场
  3. 垃圾回收器G1收费登场 是否预示Java将面临分叉威胁
  4. JDK 7中将支持正则表达式命名捕获组
  5. 探秘Java 7模块化 类路径永远消失
责任编辑:佚名 来源: 酷壳的博客
相关推荐

2009-07-24 09:41:45

Java 7 G1垃圾回收器

2009-06-02 10:18:43

Java垃圾回收器垃圾回收器Java垃圾回收

2022-02-25 08:01:34

CMS

2023-11-16 08:00:56

Java11G1

2009-06-18 13:59:33

Java SE 6垃圾回收器

2020-06-01 20:08:47

垃圾G1回收器

2021-08-10 07:00:02

Java8 G1垃圾回收器

2015-06-17 14:10:52

OracleJava 9垃圾收集器

2021-08-15 18:59:13

垃圾收集器JDK

2021-10-05 20:29:55

JVM垃圾回收器

2020-05-14 13:39:19

Java 垃圾回收机制

2017-08-04 10:53:30

回收算法JVM垃圾回收器

2022-01-20 10:34:49

JVM垃圾回收算法

2010-09-26 14:08:41

Java垃圾回收

2022-03-21 11:33:11

JVM垃圾回收器垃圾回收算法

2020-08-07 14:05:02

垃圾回收器ZGC

2011-06-28 12:39:34

Java垃圾回收

2009-04-28 13:48:09

2021-01-04 10:08:07

垃圾回收Java虚拟机

2010-12-13 11:14:04

Java垃圾回收算法
点赞
收藏

51CTO技术栈公众号