G1 collector 介绍
背景:由于CMS算法产生空间碎片和其它一系列的问题缺陷,HotSpot提供了另外一种垃圾回收策略,G1(也就是Garbage First)算法,该算法在JDK7u4版本被正式推出,官网对此描述如下:
- Can operate concurrently with applications threads like the CMS collector.
- Compact free space without lengthy GC induced pause times.
- Need more predictable GC pause durations.
- Do not want to sacrifice a lot of throughput performance.
- Do not require a much larger Java heap.
G1 is planned as the long term replacement for the Concurrent Mark-Sweep Collector (CMS). Comparing G1 with CMS, there are differences that make G1 a better solution. One difference is that G1 is a compacting collector. G1 compacts sufficiently to completely avoid the use of fine-grained free lists for allocation, and instead relies on regions. This considerably simplifies parts of the collector, and mostly eliminates potential fragmentation issues. Also, G1 offers more predictable garbage collection pauses than the CMS collector, and allows users to specify desired pause targets.
G1 Collector 是一种server风格的垃圾回收器,针对具有大内存、多cpu的机器。它在满足高吞吐量的同时,又尽可能的实现较低的GC时间,G1 Collector 主要针对以下场景:
- 像CMS一样,垃圾回收线程和应用线程并发执行
- 压缩空闲内存,避免GC导致长时间的暂停
- 能够对GC暂停时间有更好的预测
- 不希望牺牲太多的吞吐性能
- 希望可以尽可能的控制堆的大小(G1本身就是针对大堆的,一般认为4-6G以上为大堆,所以这里的大小我个人理解为在此基础上)
对于之前的garbage collectors来说(比如最早的serial、后来的parallel、CMS),它们都将堆划分成了三个部分:新生代,老年代,永久代(元空间)

G1不同,G1算法将堆划分为若干个Region,它仍然是划分代的。并且默认情况下是将堆内存划分2048份,每个region的大小也就是heap size/2048,但是region的大小只能为1M、2M、4M、8M、16M和32M,总之是2的幂次方,一般会生成2000左右个region
1. G1 Heap Structure

2. G1 Heap Allocation

如上图所示,这些region被定义为eden、survivor、old generation 逻辑上为连续的内存空间。其中eden、survivor、old generation跟以往的GC收集器一样,此外还有一个Humongous区是以往算法所没有的, 如果一个对象占用的空间超过了区域容量50%以上,G1收集器就认为这是一个巨型对象。这些巨型对象,默认直接会被分配在年老代,但是如果它是一个短期存在的巨型对象,就会对垃圾收集器造成负面影响。为了解决这个问题,G1划分了一个Humongous区,它用来专门存放巨型对象。如果一个H区装不下一个巨型对象,那么G1会寻找连续的H分区来存储。为了能找到连续的H区,有时候不得不启动Full GC。
3. Young Generation in G1

4. A Young GC in G1
存活的对象被拷贝到一个或多个survivor region中,如果某些对象的age达到了晋升老年代要求的阀值,就会晋升到老年代。(跟之前的算法差不多),G1 young gc属于stop the world (STW)性质,并且在此期间,eden region的数量和survivor region的数量会通过新一轮的计算(也就是region的数量是在动态变化的),以适应下一轮的GC更好的达到期望的暂停时间。

5. End of a Young GC with G1
存活的对象被疏散到survivor region中或者old generation region,晋升的对象由下图中暗色部分表示,蓝色的代表Survivor regions

Old Generation Collection with G1
当越来越多的对象晋升到老年代old region时,为了避免堆内存被耗尽,会触发Old Generation Collection(也可称为mixed gc),G1的old gc跟以前算法的old gc不太一样,G1 old gc是在回收整个young region的同时,还会回收一部分的old region,这里需要注意,是一部分old region,而不是全部,G1算法选择部分old region进行回收,从而可以对垃圾回收的耗时时间进行控制。触发条件:-XX:InitiatingHeapOccupancyPercent=n 当老年代大小占整个堆大小百分比达到该阈值时,会触发一次old gc
old gc执行流程:
1. initial mark: 整个过程STW,标记了从GC Root可达的对象
2. concurrent marking: 并发标记过程,整个过程gc collector线程与应用线程并行执行,找出整个堆中的存活对象
3. remark: 整个过程STW,最终标记,使用snapshot-at-the-beginning (SATB)算法(much faster than CMS use)标记出那些在并发标记过程中遗漏的,
或者内部引用发生变化的对象
4. clean up: 该过程部分是STW处理,部分是并行处理
1.统计存活对象和完全空闲的region(STW)
2.清空Remembered Sets(STW)
3.将空region加入到空闲列表中(并发)
5.Copying:整个过程STW,拷贝存活对象到新的region中
Full GC
- 并发模式失败
- 晋升失败或者疏散失败
- 增加 -XX:G1ReservePercent 选项的值(并相应增加总的堆大小),为“目标空间”增加预留内存量。
- 通过减少 -XX:InitiatingHeapOccupancyPercent 提前启动标记周期。
- 也可以通过增加 -XX:ConcGCThreads 选项的值来增加并行标记线程的数目。
- 巨型对象分配失败
G1 collector 介绍的更多相关文章
- The The Garbage-First (G1) collector since Oracle JDK 7 update 4 and later releases
Refer to http://www.oracle.com/technetwork/tutorials/tutorials-1876574.html for detail. 一些内容复制到这儿 Th ...
- CMS Collector and G1 Collector
Understanding the CMS Collector CMS has three basic operations: CMS collects the young generation (s ...
- Java Hotspot G1 GC的一些关键技术
G1 GC,全称Garbage-First Garbage Collector,通过-XX:+UseG1GC参数来启用,作为体验版随着JDK 6u14版本面世,在JDK 7u4版本发行时被正式推出,相 ...
- java GC垃圾回收机制G1、CMS
CMS(Concurrent Mark-Sweep)是以牺牲吞吐量为代价来获得最短回收停顿时间.对于要求服务器响应速度的应用上,这种垃圾回收器非常适合.在启动JVM参数加上-XX:+UseConcMa ...
- 弄明白CMS和G1,就靠这一篇了
目录 1 CMS收集器 安全点(Safepoint) 安全区域 2 G1收集器 卡表(Card Table) 3 总结 4 参考 在开始介绍CMS和G1前,我们可以剧透几点: 根据不同分代的特点,收集 ...
- G1垃圾收集器官方文档透彻解读【官方解读】
在前几次中已经对G1的理论进行了一个比较详细的了解了,对于G1垃圾收集器最权威的解读肯定得上官网,当咱们将官网的理解透了,那基本上网上对于G1的说明其实最终都是来自于官网,所以接下来会详细来解读Ora ...
- 提交并发量的方法:Java GC tuning :Garbage collector
三色算法,高效率垃圾回收,jvm调优 Garbage collector:垃圾回收器 What garbage? 没有任何引用指向它的对象 JVM GC回收算法: 引用计数法(ReferenceCou ...
- Garbage Collectors – Serial vs. Parallel vs. CMS vs. G1 (and what’s new in Java 8)
转自:http://blog.takipi.com/garbage-collectors-serial-vs-parallel-vs-cms-vs-the-g1-and-whats-new-in-ja ...
- Garbage Collectors - Serial vs. Parallel vs. CMS vs. G1 (and what's new in Java 8)--转
The 4 Java Garbage Collectors - How the Wrong Choice Dramatically Impacts Performance The year is 20 ...
随机推荐
- Java 多线程部分面试题
1..什么是线程,什么是进程,它们有什么区别和联系,一个进程里面是否必须有个线程 进程和线程的主要差别在于它们是不同的操作系统资源管理方式.进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它 ...
- PHP语句中or的用法
经常看到这样的语句: $file = fopen($filename, 'r') or die("抱歉,无法打开: $filename"); or在这里是这样理解的,因为在P ...
- 华三F100 系列防火墙 - 浮动路由联动NQA 实现双线路自动切换
公司 有两条公网线路,一条移动作为日常主用线路,一条联通作为备用线路. 为了实现主备线路自动切换,配置了浮动路由 但浮动路由只能在 主用接口为down状态时才能浮出接管默认路由.如果故障为非物理链路故 ...
- HTTP_2_HTTP协议概要
http协议概要 HTTP 通信对象 通信方式 通信状态 定位资源 节省通信量 超文本传输协议 客户端与服务器端 请求和响应 不保存状态(借助cookie) 请求URI keep-alive/pipe ...
- 使用ASM实现动态代理
如果对我这段代码感兴趣,直接拷贝测试debug,要不然你不知道我写的是什么鬼,如果有什么问题,可以告诉我. 一.实现动态代理,首先得考虑有应该定义哪些类,根据JDK的动态代理思想,那么它就应该有一个生 ...
- 【Mac】nsurlsessiond 后台下载问题的解决方法
最近在使用 Mac 系统的时候,经常发现 nsurlsessiond 这个进程,一直在后台下载,非常占用网速.解决方案如下: 通过终端执行下面的语句可以停止后台的自动更新: #!/bin/sh lau ...
- java8中用流收集数据
用流收集数据 汇总 long howManyDishes = menu.stream().collect(Collectors.counting()); int totalCalories = men ...
- Unity经典游戏编程之:球球大作战
版权声明: 本文原创发布于博客园"优梦创客"的博客空间(网址:http://www.cnblogs.com/raymondking123/)以及微信公众号"优梦创客&qu ...
- vue-cli项目下引入vant组件
前言 Vant是有赞前端团队基于有赞统一的规范实现的 Vue 组件库,提供了一整套 UI 基础组件和业务组件.通过 Vant,可以快速搭建出风格统一的页面,提升开发效率.目前已有近50个组件,这些组件 ...
- .Net Core 最优 MD5 打开方式!初学者建议收藏(支持 SHA1,SHA256,.Net Framework)
public static string GetMd5Hash(string input) { using (MD5 md5Hash = MD5.Create()) { // Convert the ...