概述

垃圾收集器是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垃圾收集器整理的更多相关文章

  1. 7种JVM垃圾收集器特点,优劣势、及使用场景

    今天继续JVM的垃圾回收器详解,如果说垃圾收集算法是JVM内存回收的方法论,那么垃圾收集器就是内存回收的具体实现. 一.常见的垃圾收集器有3类 1.新生代的收集器包括 Serial PraNew Pa ...

  2. 【006】【JVM——垃圾收集器总结】

     Java虚拟机学习总结文件夹 JVM--垃圾收集器总结 垃圾收集器概览 收集算法是内存回收的方法论.垃圾收集据是内存回收的详细实现.Java虚拟机规范中对垃圾收集器应该怎样实现没有规定.不同的厂 ...

  3. 第五章 JVM垃圾收集器(1)

    说明:垃圾回收算法是理论,垃圾收集器是回收算法的实现,关于回收算法,见<第四章 JVM垃圾回收算法> 1.七种垃圾收集器 Serial(串行GC)-- 复制 ParNew(并行GC)-- ...

  4. JVM垃圾收集器(1)

    此文已由作者赵计刚薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 说明:垃圾回收算法是理论,垃圾收集器是回收算法的实现,关于回收算法,见<第四章 JVM垃圾回收算法& ...

  5. 5种JVM垃圾收集器特点和8种JVM内存溢出原因

    先来看看5种JVM垃圾收集器特点 一.常见垃圾收集器 现在常见的垃圾收集器有如下几种: 新生代收集器: Serial ParNew Parallel Scavenge 老年代收集器: Serial O ...

  6. 7种 JVM 垃圾收集器特点、优劣势及使用场景(多图)

    7种 JVM 垃圾收集器特点.优劣势及使用场景(多图)  mp.weixin.qq.com 点击上方"IT牧场",选择"设为星标"技术干货每日送达! 一.常见垃 ...

  7. JVM调优:HotSpot JVM垃圾收集器

    HotSpot JVM垃圾收集器 - Snooper - 博客园https://www.cnblogs.com/snooper/p/8718478.html

  8. JVM垃圾收集器-Parallel Scavenge收集器

    今天我给大家讲讲JVM垃圾收集器-Parallel Scavenge收集器 Parallel Scavenge收集器 Parallel Scavenge收集器也是一个新生代收集器,它也是使用复制算法的 ...

  9. 第六章 JVM垃圾收集器(2)

    上一章记录了几种常见的垃圾收集器,见<第五章 JVM垃圾收集器(1)> 1.G1 说明: 从上图来看,G1与CMS相比,仅在最后的"筛选回收"部分不同(CMS是并发清除 ...

随机推荐

  1. Android - shape圆形画法(oval)

    shape圆形画法(oval) 本文地址: http://blog.csdn.net/caroline_wendy 1. 创建一个目录drawable, 用于存放xml类型的图片资源; 2. 在dra ...

  2. 一种使用GDI+对图片尺寸和质量的压缩方法

    今天同事向我询问图片压缩的算法.我想起大概两三年前做过的一个项目. 当中包括了尺寸和质量两种压缩算法.而且支持JPEG.bmp.PNG等格式. 今天把这段逻辑贴出来,供大家參考.(转载请指明来源于br ...

  3. 载入DLL中的图片资源生成Skia中的SkBitmap对象

    PPAPI Plugin在Windows下是DLL,能够嵌入图片文件.使用Skia画图时须要依据DLL里的图片文件生成SkBitmap对象. 以下是代码: #include "utils.h ...

  4. 每天一个JavaScript实例-防止反复表单提交

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  5. EEPlat PaaS 整体方案及技术原理

    EEPlat PaaS平台提供了基于元数据驱动的以配置为主的高速开发平台,同一时候提供了完整的多租户实现,各租户拥有自己的独立应用和数据库,租户间实现了应用和数据的全然隔离. EEPlat PaaS平 ...

  6. File attachment or query results size exceeds allowable value of 1000000 bytes.

    今天早晨,收到了作业执行失败的邮件(前几天还能正常执行该作业.不知为何今天出错) 邮件显示,作业的第三个步骤报错. step3内容: msdb.dbo.sp_send_dbmail     @prof ...

  7. [NOIP复习]第三章:动态规划

    一.背包问题 最基础的一类动规问题.相似之处在于给n个物品或无穷多物品或不同种类的物品,每种物品仅仅有一个或若干个,给一个背包装入这些物品,要求在不超出背包容量的范围内,使得获得的价值或占用体积尽可能 ...

  8. git更新失败Probably the path to Git executable is not valid

    git更新代码失败 检查setting配置,发现路径配置错误 找对git的安装目录,修改路径后保存即可

  9. springboot命令启动

    gradle打jar包命令 jar { doFirst { def jarFiles = ''; configurations.compile.collect { jarFiles += it.nam ...

  10. 2017年国内常用的公共NTP服务

    安卓机顶盒里常用的 http://cn.pool.ntp.org CERNET 的一堆服务器就在那里面 http://asia.pool.ntp.org 追踪它的IP,台湾.韩国.日本都有. 阿里云 ...