深入理解JVM 垃圾收集器(下)G1收集器
- 1.回顾CMS
- 1.1堆内存结构
- 1.2新生代GC
- 1.3老年代GC
- 2.G1收集器
- 2.1G1实现概览及使用场景
- G1的推荐使用场景
- 2.2GC
- 2.2.1新生代GC
- 2.2.2老年代GC
- 老年代GC总结
- 2.2.3 其他
- 2.4 最佳实践
- 2.4.1 JVM参数
- 基本参数设置
- 关键参数设置
- 2.4.1 JVM参数
- 2.1G1实现概览及使用场景
- 3.参考资料
1.回顾CMS
1.1堆内存结构

新生代分为Eden区和两个survivor区。老年代是一块连续区域。
只有FullGC时才可能发生内存整理。
1.2新生代GC

新生代淡绿色,老年代蓝色。系统运行一段时间后CMS堆内存可能如下图所示,对象分散在老年代各处。

新生代存活对象从Eden区和survivor区复制到另一个空闲的survivor区。任何minorGC年龄达到阈值的老对象被升级至老年代。

youngGC(minorGC)后,Eden区和一个survivor区被清空。
新近升级至老年代的对象以深蓝色表示。绿色对象是新生代仍存活的对象。
1.3老年代GC

在初始标记和重新标记阶段发生STW。当老年代剩余空间达到阈值时(发生Concurrent Mode Failure),使用SerialOld替代CMS进行老年代GC。
(1)初始标记停顿时间很短,简单的标记GCRoot引用的对象。(2)并发标记在标记存活对象时,应用继续执行。(3)重新标记阶段,标记并发阶段遗漏的存活对象。


未被标记的对象直接被回收。完成并发清扫后,许多老年代空间被释放出来。同时内存整理仍没有发生,老年代存在大量内存碎片。
最终,CMS经过重置阶段,等待下一次GC。
2.G1收集器
2.1G1实现概览及使用场景



G1收集器将java堆均分成大小相同的区域(region,1M-32M,最多2000个,最大支持堆内存64G)。一个或多个不连续的区域共同组成eden、survivor或old区,但大小不再固定,这为内存应用提供了极大地弹性。G1垃圾收集过程与CMS类似。G1在堆内存中并发地对所有对象进行标记,决定对象的可达性。经过全局标记,G1了解哪些区域几乎是空的,然后优先收集这些区域,这就是GarbageFirst的命名由来。G1将垃圾收集和内存整理活动专注于那些几乎全是垃圾的区域,并建立停顿预测模型来决定每次GC时回收哪些区域,以满足用户设定的停顿时间。
对于区域的回收通过复制算法实现。在完成标记清理后,G1将这几个区域的存活对象复制到一个单独区域中,实现内存整理和空间释放。这一过程通过多线程并行进行来降低停顿时间,提高吞吐量。通过这样的方式,G1在每次GC过程中持续清理碎片,控制停顿时间满足用户要求。这时过去虚拟机无法做到的。CMS不清理内存碎片(除非通过虚拟机参数设置,在每次或多次FullGC后进行整理),ParallelOld进行全堆整理,会导致较长的停顿时间。
G1不是实时垃圾收集器,它会尽量让停顿时间低于用户设置的停顿时间目标但不能保证一定如此。G1根据历史垃圾收集监测数据来 预测每个区域的回收时间,然后根据用户设定的目标停顿时间决定每次GC时可以回收哪些区域。G1通过这种方式建立比较精确的区域回收时间预测模型。
G1的推荐使用场景
G1的设计初衷是为用户提供大内存、低GC停顿时间的应用解决方案。这意味着堆内存6G或更大,停顿时间稳定且少于0.5秒。
如果应用正在使用CMS或ParallelOld且面临以下问题,推荐将应用迁移至G1
- FullGC发生频繁或总时间过长
- 对象分配率或对象升级至老年代的比例波动较大
- 较长的垃圾收集或内存整理停顿(大于0.5至1秒)
注意:如果应用没有上述问题,不需要迁移虚拟机。G1并不是最新JDK要求的虚拟机。
2.2GC
2.2.1新生代GC


存活对象移动到一个或多个survivor区域。如果对象达到晋升年龄,将被移动到老年代区域。
新生代GC总结:
新生代垃圾回收(youngGC)需要STW,所有应用线程需要停顿。
youngGC多线程并行执行。
存活对象复制到新的survivor区或老年代区。
2.2.2老年代GC
|
阶段
|
描述
|
说明
|
|---|---|---|
|
初始标记 (Stop the world) |
标记GC Roots直接引用的对象,新生代直接引用的老年代对象。 |
|
| 并发标记 |
标记堆中所有存活的对象。与用户的应用程序并发执行。 在并发标记阶段,若发现区域对象中的所有对象都是垃圾,那个这个区域会在重新标记阶段被立即回收。 同时,并发标记过程中,会计算每个区域的对象活性(区域中存活对象的比例)。 |
|
|
重新标记 (Stop the world) |
修正并发标记阶段因用户程序继续运行而导致标记发生变动的那一部分标记记录 如果发现完全没有活对象的region就会将其回收到空闲列表。 |
|
|
清除 (Stop the world) |
清点和重置阶段。 1)使用marking bitmap统计每个region被标记为活的对象有多少,统计每个区域的对象活性(区域中存活对象的比例)。 2)重置Remembered Sets |
|
|
复制 (Stop the world) |
将存活的对象复制到未使用的region中。 G1选择那些活跃度最低,回收速度最快的区域进行回收。 |
|
老年代GC总结
- 并发标记阶段
- 区域活跃度信息的统计与应用线程并发进行
- 活跃度信息决定了那个区域最先在清理阶段被回收
- 没有CMS的清理阶段
- 再次标记阶段
- SATB算法比CMS使用的算法更快
- 空区域在这个阶段被回收
- 复制/清理阶段
- 新生代和老年代同时被回收
- 老年代根据活跃度确定回收优先级
2.2.3 其他
Remembered Set(可认为是GC Roots的补充)
每一个Region都有一个对应的Remembered Set,里面记录了所有来自外部的引用,这些引用将被认为是GC roots的补充。

2.4 最佳实践
2.4.1 JVM参数
基本参数设置
以下是使用G1收集器的javademo演示
java -Xmx50m -Xms50m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar c:\javademos\demo\jfc\Java2D\Java2demo.jar
关键参数设置
- -XX:+UseG1GC - 启用G1
- -XX:MaxGCPauseMillis=200 - GC停顿的最长时间。这是一个软目标,即虚拟机会尽最大可能满足这一时间,但某些情况下仍可能超过。默认值为200ms。
- -XX:InitiatingHeapOccupancyPercent=45 - 堆内存使用率达到多少时启动一次GC过程。GC过程涉及整个堆内存,不单指某个年龄代。设为0时表示循环进行并发GC。默认值为45,即堆内存使用45%后触发一次GC。
3.参考资料
http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/G1GettingStarted/index.html Getting Started with the G1 Garbage Collector
https://www.cnblogs.com/oldtrafford/p/6883796.html Getting Started with the G1 Garbage Collector(中文)
https://www.jianshu.com/p/74dd0ffd4386?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation Java垃圾回收手册(四):垃圾回收算法实现
http://blog.jobbole.com/109170/ 深入理解Java G1垃圾收集器
http://hllvm.group.iteye.com/group/topic/44381 高级语言虚拟机论坛 [资料] [HotSpot VM] 请教G1算法的原理
深入理解JVM 垃圾收集器(下)G1收集器的更多相关文章
- CMS收集器和G1收集器优缺点
首先要知道 Stop the world的含义(网易面试):不管选择哪种GC算法,stop-the-world都是不可避免的.Stop-the-world意味着从应用中停下来并进入到GC执行过程中去. ...
- JVM-如何判断对象存活与否与CMS收集器和G1收集器的区别
JVM如何判断对象存活? 1.计数器 2.可达性分析 (很多主流语言采用这种方法来判断对象是否存活) 计数器:每当有一个地方引用该对象时,计数器 +1:引用失效则 -1: 优点:实现简单,判定效率 ...
- CMS收集器和G1收集器 他们的优缺点对比 G1只有并发标记才不会stop-the-world 其他都会停下来(阿里多次问到)
CMS收集算法 参考:图解 CMS 垃圾回收机制原理,-阿里面试题 G1收集算法 参考:G1 垃圾收集器入门 首先要知道 Stop the world的含义(网易面试):不管选择哪种GC算法,stop ...
- 垃圾收集器之:G1收集器
G1垃圾收集器是一种工作在堆内不同分区上的并发收集器.分区既可以归属于老年代,也可以归属新生代,同一个代的分区不需要保持连续.为老年代设计分区的初衷是我们发现并发后台线程在回收老年代中没有引用的对象时 ...
- CMS垃圾收集器与G1收集器
1.CMS收集器 CMS收集器是一种以获取最短回收停顿时间为目标的收集器.基于“标记-清除”算法实现,它的运作过程如下: 1)初始标记 2)并发标记 3)重新标记 4)并发清除 初始标记.从新标记这两 ...
- CMS收集器和G1收集器
CMS收集器 CMS收集器是一种以获取最短回收停顿时间为目标的收集器.基于"标记-清除"算法实现,它的运作过程如下: 初始标记 并发标记 重新标记 并发清除 初始标记.从新标记这两 ...
- G1收集器-原创译文[未完成]
G1收集器-原创译文 原文地址 Getting Started with the G1 Garbage Collector 目的 本文介绍了如何使用G1垃圾收集器以及如何与Hotspot JVM一起使 ...
- G1收集器
转载:https://blog.csdn.net/zhou2s_101216/article/details/79202893 http://blog.jobbole.com/109170/ http ...
- JVM垃圾收集器-G1收集器
G1收集器是当前收集器技术发展的最前沿成果,在JDK1.6_Updata14中提供了Early Access版本的G1收集器以供适用.G1收集器是垃圾收集器理论进一步发展的产物,它与前面的CMS收集器 ...
随机推荐
- 下载VMware
1.进入VMware官网:http://www.vmware.com/cn 2.找到下载,点击Workstation Pro,此时需要账号登录. 3.选择需要下载的版本.对应的操作系统,点击转至下载
- Adapter适配器 final int Id 导致选中的Item不在当前界面
写了上面这么一个横向混动,点击切换到,哪个的Item上就会有一个 常用 的小图标.但是我每次滑动切换到后面 成龙9这个Item,这个 常用的图片,也在 这个上面了,但是他一更新,就变成 等你再 ...
- PhoneGap 第一个程序
首先,现在PhoneGap ZIP包. index.html <!DOCTYPE HTML lang="zh-CN"> <html> <head&g ...
- cxGrid 循环选择条目
Delphi DevExpress CxGrid 循环选择条目 整理出来的,直接复制粘贴即可使用 以下是从网络上复制粘帖到的,实践证明,利用以下代码进行获取选择行是错误的. 当我们利用 CxGrid进 ...
- 【BZOJ5060】魔方国 特判
[BZOJ5060]魔方国 Description 小奇和魔法猪打开了战狂的遗迹,穿越到了东元20年.东元元年,战狂率领一千万士兵毁灭了一个又一个文明,并建立起了新文明——昌和帝国,招募了八位伟人:大 ...
- :nth- 从1开始计数,其他如:eq()、 index()从0开始计数
因为jQuery的实现:nth-是严格来自CSS规范,n值是“1-indexed”,也就是说,从1开始计数. 对于所有其他选择器表达式比如:eq() 或 :even ,jQuery遵循JavaScri ...
- Windows服务的调试
1.服务为其他程序调用的情况:首先停止服务,在项目中设置断点,重新启动服务,点击项目中工具,附加到进程,运行调用服务的程序,即可进入之前设置的断点,进而进行调试. 2.服务内方法为自动执行的情况:首先 ...
- 搜索过滤grep(win下为findstr)
搜索过滤grep(win下为findstr) 1.主要参数 [options]主要参数: -c:只输出匹配行的计数. -i:不区分大小写 -h:查询多文件时不显示文件名. -l:查询多文件时只输出包含 ...
- CNI Proposal 摘要
原文连接:https://github.com/containernetworking/cni/blob/master/SPEC.md General consideration CNI的想法是先让容 ...
- django博客项目2.建立 Django 博客应用
建立博客应用 我们已经建立了 Django 博客的项目工程,并且成功地运行了它.不过到目前为止这一切都还只是 Django 为我们创建的项目初始内容,Django 不可能为我们初始化生成博客代码,这些 ...





