1.1 G1收集器的设计目标
先介绍两个概念:吞吐量和响应能力,响应能力和吞吐量是评价一个系统的两个重要指标
吞吐量
吞吐量关注的是,在一个指定的时间内,最大化一个应用的工作量。
如下方式来衡量一个系统吞吐量的好坏:
在一定时间内同一个事务(或者任务、请求)完成的次数(tps)
数据库一定时间以完成多少次查询
对于关注吞吐量的系统,一定次数卡顿(即stw)是可以接受的,因为这个系统关注长时间的大量任务的执行能力,单次快速的响应并不值得考虑
响应能力
响应能力指一个程序或者系统对请求是否能够及时响应,比如:
一个桌面UI能多快地响应一个事件
一个网站能够多快返回一个页面请求
数据库能够多快返回查询的数据
对于这类对响应能力敏感的场景,长时间的停顿是无法接受的,关注每一次反应的能力。
-
g1收集器是一个面向服务端的垃圾收集器适用于多核处理器、大内存容量的服务端系统。
-
它满足短时间gc停顿的同时达到一个较高的吞吐量。
-
JDK7以上版本适用
与应用线程同时工作,几乎不需要 stop the work(与CMS类似);
-
G1的设计规划是要替换掉CMS,G1在某些方面弥补了CMS的不足,比如CMS使用的是mark-sweep算法,自然会产生内存碎片(CMS只能在Full GC时,用 stop the world整理内存碎片),然而G1基于copying算法,高效的整理剩余内存,而不需要管理内存碎片
-
GC停顿更加可控,甚至可以设置一个时间阈值,比如说可以回收某些部分的老年代,而不像CMS老年代必须全部回收(其它收集器时间可能难以把握)
1.2 G1重要概念
1.2.1 分区( Region)
-
G1采取了不同的策略来解决并行、串行和CMS收集器的碎片、暂停时间不可控等问题—G1将整个堆分成相同大小的分区或称为区域( Region)
-
G1的堆结构如下:
-
每个分区都可能是年轻代也可能是老年代,但是在同一时刻只能属于某个代。年轻代,survivor区,老年代这些概念还存在,成为逻辑上的概念,这样方便复用之前分代框架的逻辑。分区在物理上不需要连续,则带来了额外的好处,可以在老年代中只对某些区域(Region)进行回收。对于新生代依然是在新生代满了的时候,对整个新生代进行回收一一整个新生代中的对象,要么被回收、要么晋升,至于新生代也采取分区机制的原因,则是因为这样跟老年代的策略统一,方便调整代的大小【其实新生代并不适合这样的垃圾收集,因为是对新生代的所有区域进行回收!不用像老年代那样选择回收效益高的Region】
-
在G1中,还有一种特殊的区域,叫 Humongous区域。如果一个对象占用的空间达到或是超过了分区容量50%以上,G1收集器就认为这是一个巨型对象。这些巨型对象,默认直接会被分配在老年代,但是如果它是一个短期存在的巨型对象就会对垃圾收集器造成负面影响。为了解决这个问题,G1划分了一个 Humongous 区,它用来专门存放巨型对象。如果一个H区装不下一个巨型对象,那么G1会寻找连续的H分区来存储。为了能找到连续的H区,有时候不得不启动Full GC。
-