JVM垃圾收集器整理
概述
垃圾收集器是jvm实现内存回收的具体实现。本次分享要介绍的7种垃圾收集器的作用区域及其之间的关系如下图:
注:
- 如果2个垃圾收集器之间有连线,表示可以搭配使用
- 垃圾收集器并没有最好的,只有针对不同应用场景最合适的
(1)Serial收集器
| 算法 | 内存区域 | 执行方式 |
|---|---|---|
| 复制算法 | 新生代 | 单线程、串行 |
过程
先暂停全部用户线程(Stop The World),然后开启一条GC线程使用复制算法对垃圾进行回收。直到收集结束被暂停的线程才能继续执行
特点
- 简单而高线,对单CPU环境没有线程交互的开销。
- 由于单线程运行,且整个GC阶段都要暂停用户线程,因此会造成应用程序停顿。
- client模式下的默认垃圾收集器
使用场景
平时的开发与调试程序使用,以及桌面应用交互程序。
(2)Serial Old收集器
| 算法 | 内存区域 | 执行方式 |
|---|---|---|
| 标记/整理算法 | 老年代 | 单线程、串行 |
执行过程、特点、使用场景与Serial收集器类似
(3)ParNew收集器
| 算法 | 内存区域 | 执行方式 |
|---|---|---|
| 复制算法 | 新生代 | 多线程、并行 |
过程
开启多个GC线程使用复制算法并行进行垃圾回收 
特点
- 使用多个线程去并行执行垃圾回收,在发挥多处理器的优势
- 在单处理器上的性能会低于Serial收集器(线程交互开销)
- 执行垃圾回收也需要暂停其他用户线程
使用场景
在中到大型的堆上,且系统处理器至少多于一个的情况。
(4)Parallel Scavenge收集器
| 算法 | 内存区域 | 执行方式 |
|---|---|---|
| 复制算法 | 新生代 | 并行 |
过程
ParNew收集器基本类似,只不过优先满足最大停顿时间的目标,次之是吞吐量,最后才是新生代区域的最小值。
吞吐量=运行用户代码的时间/CPU总消耗时间
特点
- 更精确的控制GC停顿时间以及吞吐量
- 控制最大的停顿时间(使用-XX:MaxGCPauseMillis=),以及控制吞吐量(使用-XX:GCTimeRatio=)
使用场景
适用于与用户交互的程序,良好的响应速度能提升用户体验,高吞吐量则可以高效的利用cpu。主要适合在后台运算而不需要太多交互的任务
Parallel Old收集器
| 算法 | 内存区域 | 执行方式 |
|---|---|---|
| 标记/整理算法 | 老年代 | 并行 |
特点
除了serial old以外唯一一个可以与parallel scavenge搭配工作的年老代搜集器
CMS收集器
| 算法 | 内存区域 | 执行方式 |
|---|---|---|
| 标记/清除算法 | 老年代 | 多线程、并行 |
过程
- 初始标记(CMS initial mark):需要用户线程停顿。标记一下GC Roots能直接关联到的对象
- 并发标记(CMS concurrent mark):以初始标记的对象为root进行并发标记。
- 重新标记(CMS remark):需要用户线程停顿,是为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录。
- 并发清除(CMS concurrent sweap):清除标记的对象

特点
1.会有2次Stop The World
1.初始标记阶段,时间很短,只会标记直接与GC Root相连的对象 2.重新标记阶段,时间比初始化标记稍长
2.浮动垃圾
产生原因
在进行标记阶段,标记的对象不再从GC Root可达,因此在这次GC过程中该对象内存空间不会被回收,因此造成了浮动垃圾。
影响
这些浮动垃圾会占用一些内存,但下次GC会被回收。
3.三色标记法
产生原因
在并发标记阶段,GC线程没有标记(用户线程之前没在用),在标记过程中,用户线程又重新引用了该对象。如果该对象依然被回收,那么程序就直接报错了。
标记过程
下面举个例子说明,设计A是被GC Root相关联的对象,假设现在正在搜索A相关联的对象,这个时候A被标记为灰色,搜索到A引用了B,这个时候B也会被标记为灰色,如下图
当A搜索完以后,A被标记为绿色,这个时候直接与A相连的B和C已被标记为灰色,但D没有,因为D没有直接与A相连,如下图
然后继续搜索B直接引用的对象,假设这个过程中,C不再引用D,如下图
如果在搜索C相关的引用后,D依然处于不可达的状态,假设这个时候已经标记完成的对象B引用了D,如下图 如果D被回收,那么在后面的程序肯定会有问题
解决办法
此时的解决办法就是有一个叫做写入屏障(注意在G1收集器中会比较)的东西。就是说,如果B已经被标记了(已经是绿色的了),那么用户线程改动 B->D的时候,会把D变成灰色,这样,以后就可以搜索D了。
4.Concurrent Mode Failure
由于其他垃圾回收器都是 "stop the world",那么内存不够了就执行 GC。但是 CMS 垃圾回收器是可以和用户线程一起并发的。假设在执行GC过程中内存不够了怎么办?这个时候就会有预备方案,Serial Old 垃圾回收器会替代 CMS,进行 "stop the world"垃圾收集。
使用-XX:CMSInitiatingOccupancyFraction的值来设定触发GC的内存百分比
5.空间碎片
CMS是一款基于“标记-清除”算法实现的收集器,收集结束时会有大量的空间碎片产生。当无法找到足够大的连续空间来分配当前对象,不得不提前触发一次full Gc。
-XX:+UseCMSCompactAtFullCollection
默认是打开的,用户在CMS收集器顶不要进行Full GC时开启内存碎片的合并整理过程,内存整理的过程是无法并发的,空间碎片的问题没有了,但停顿的时间会变长
-XX:CMSFullGCBeforeCompaction
设置多少次不压缩Full GC后,跟着来一次带压缩的碎片整理,默认为0。
6.吞吐量影响
CMS收集器对CPU资源非常敏感.CMS默认启动的回收线程数是(CPU数量+3)/4,在并发阶段,它虽然不会导致用户线程停顿,但是会占用一部分线程而导致应用程序变慢,总吞吐量对降低。
使用场景
重视服务的响应速度,希望系统的停顿时间最短,以带来较好的用户体验,例如互联网站或B/S系统的服务端上,
G1收集器
CMS垃圾收集器虽然减少了暂停应用程序的运行时间,但是它还是存在着内存碎片问题。于是,为了去除内存碎片问题,同时又保留CMS垃圾收集器低暂停时间的优点,JAVA7发布了一个新的垃圾收集器 - G1垃圾收集器。
内存组织方式变更
Eden,Survivor和Tenured等内存区域不再是连续的了,而是变成了一个个大小一样的region - 每个region从1M到32M不等。一个region有可能属于Eden,Survivor或者Tenured内存区域。 在G1中,还有一种特殊的区域,叫Humongous区域。 如果一个对象占用的空间超过了分区容量50%以上,G1收集器就认为这是一个巨型对象。G1划分了一个Humongous区,它用来专门存放巨型对象。如果一个H区装不下一个巨型对象,那么G1会寻找连续的H分区来存储。为了能找到连续的H区,有时候不得不启动Full GC。
新生代收集
在G1垃圾收集器中CMS垃圾收集器差不多,回收Eden region和Survivor region上的非可达对象,同时升级存活的可达对象到对应的Survivor region或Tenured region上。 
老年代收集
对于年老代上的垃圾收集,G1垃圾收集器也分为4个阶段,基本跟CMS垃圾收集器一样,但略有不同:
- 初始化标记:过程和CMS基本类似,不同的是该阶段在触发YGC的时候执行(有什么好处?)
- 并发标记阶段:和CMS基本类似,不同的是在该阶段,G1会计算每个 region的对象存活率,方便后面的clean up阶段使用。
- 重新标记:和CMS基本类似,但采取算法不一样,G1采用一种叫做SATB(snapshot-at-the-begining)的算法能够在重新阶段更快的标记可达对象。(CMS是使用写入屏障)
- Clean up/Copy阶段 - 在G1中,没有CMS中对应的并发清楚阶段。相反 它有一个Clean up/Copy阶段,在这个阶段中,G1会挑选出那些对象存活率低的region进行回收,这个阶段也是和minor gc一同发生的,如下图所示
JVM垃圾收集器整理的更多相关文章
- 7种JVM垃圾收集器特点,优劣势、及使用场景
今天继续JVM的垃圾回收器详解,如果说垃圾收集算法是JVM内存回收的方法论,那么垃圾收集器就是内存回收的具体实现. 一.常见的垃圾收集器有3类 1.新生代的收集器包括 Serial PraNew Pa ...
- 【006】【JVM——垃圾收集器总结】
Java虚拟机学习总结文件夹 JVM--垃圾收集器总结 垃圾收集器概览 收集算法是内存回收的方法论.垃圾收集据是内存回收的详细实现.Java虚拟机规范中对垃圾收集器应该怎样实现没有规定.不同的厂 ...
- 第五章 JVM垃圾收集器(1)
说明:垃圾回收算法是理论,垃圾收集器是回收算法的实现,关于回收算法,见<第四章 JVM垃圾回收算法> 1.七种垃圾收集器 Serial(串行GC)-- 复制 ParNew(并行GC)-- ...
- JVM垃圾收集器(1)
此文已由作者赵计刚薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 说明:垃圾回收算法是理论,垃圾收集器是回收算法的实现,关于回收算法,见<第四章 JVM垃圾回收算法& ...
- 5种JVM垃圾收集器特点和8种JVM内存溢出原因
先来看看5种JVM垃圾收集器特点 一.常见垃圾收集器 现在常见的垃圾收集器有如下几种: 新生代收集器: Serial ParNew Parallel Scavenge 老年代收集器: Serial O ...
- 7种 JVM 垃圾收集器特点、优劣势及使用场景(多图)
7种 JVM 垃圾收集器特点.优劣势及使用场景(多图) mp.weixin.qq.com 点击上方"IT牧场",选择"设为星标"技术干货每日送达! 一.常见垃 ...
- JVM调优:HotSpot JVM垃圾收集器
HotSpot JVM垃圾收集器 - Snooper - 博客园https://www.cnblogs.com/snooper/p/8718478.html
- JVM垃圾收集器-Parallel Scavenge收集器
今天我给大家讲讲JVM垃圾收集器-Parallel Scavenge收集器 Parallel Scavenge收集器 Parallel Scavenge收集器也是一个新生代收集器,它也是使用复制算法的 ...
- 第六章 JVM垃圾收集器(2)
上一章记录了几种常见的垃圾收集器,见<第五章 JVM垃圾收集器(1)> 1.G1 说明: 从上图来看,G1与CMS相比,仅在最后的"筛选回收"部分不同(CMS是并发清除 ...
随机推荐
- iKcamp团队制作|基于Koa2搭建Node.js实战(含视频)☞ 中间件用法
中间件用法--讲解 Koa2 中间件的用法及如何开发中间件
- 动手开发一个名为“微天气”的微信小程序(上)
引言:在智能手机软件的装机量中,天气预报类的APP排在比較靠前的位置.说明用户对天气的关注度非常高.由于人们不管是工作还是度假旅游等各种活动都须要依据自然天气来安排.跟着本文开发一个"微天气 ...
- 掌上快递 APP 项目之概述篇
概述 学习Android开发也有一段时间了,利用业余时间独立制作的一款快递类APP软件.大概2个多星期吧,自己将其定位为"集快递信息追踪.附近快递点查询. 快递公司投诉功能为一体的便民生活类 ...
- hdu 1233 还是畅通project(kruskal求最小生成树)
还是畅通project Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tota ...
- websocket简单实例
只需要两个文件即可,一个服务端,一个前端,一下示例为模拟简单的聊天程序: 服务端: package com.test.websocket; import java.io.IOException; im ...
- (转)java中的方法区
首先要说明的是,此文章转载自 http://blog.csdn.net/zzhangxiaoyun/article/details/7518917 谢谢作者.是本人认为对方法区解释得比较清楚的一篇文章 ...
- CentOS下nginx php mysql 环境搭建
CentOS下搭建PHP运行环境. 首先是在虚拟机上装好一个命令行的CentOS,如果只是弄服务器的话,不要装图形界面,会比较卡. 一.安装编译工具及库文件 yum -y install make z ...
- NanUI文档 - 开始使用NanUI
NanUI文档目录 NanUI简介 开始使用NanUI 打包并使用内嵌式的HTML/CSS/JS资源 使用网页来设计整个窗口 如何实现C#与Javascript相互掉用(待更新...) 如何处理Nan ...
- IntelliJ IDEA 热部署插件 JRebel 安装激活及使用
JRebel对个人用户免费使用,但是要使用Facebook账号把信息完整填写之后才能获取Lisense,登陆Facebook官网二种方案:①修改本地hosts文件:②使用VPNFQ 以下是二种方案的解 ...
- iOS 计时器三种定时器的用法NSTimer、CADisplayLink、GCD
原文:http://www.cocoachina.com/ios/20160919/17595.html DEMO链接