概述

垃圾收集器是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. Python+Selenium webdriver Api

    # -*- coding: utf-8 -*- from selenium import webdriver browser = webdriver.Firefox() #browser.set_wi ...

  2. PHP 数据库连接池实现

    摘要 xml 读取配置文件 简易方式 常规方式 PHP解析XML 配置文件 解析 数据库连接池 測试 申请过多时拒绝请求 已满后拒绝放入 总结 摘要 之前总是以脚本面向过程的方式写PHP代码,所以非常 ...

  3. 前端笔记---塌陷top

    一.在设置盒子div的子元素的外边框margin-top,子元素属性不起作用,父元素下沉: <!DOCTYPE html> <html lang="en"> ...

  4. intellij idea 主题大全,看不惯idea 那2种主题的来这里了

    一直用默认的主题,但是白色的背景看久了会晃眼睛.所以打算换成黑色的. 不过Intellij只有两种主题,Default和Darcula. 现在只能自己手动安装一个了.新主题需要满足, 看久了不会太累. ...

  5. Web API的CORS

      Web API中进行跨域需要在请求头中加入允许跨域请求 Access-Control-Allow-Origin=* 上面代码代表允许所有跨域请求.当然也可以只允许某个站点进行跨域请求,只需将'*' ...

  6. C语言中一些不被熟知的特性

    designated initializers(c99) C99允许你对结构体中指定的变量初始化,如 struct Foo { int x; int y; int z; }; }; 指定初始化也可适用 ...

  7. SQL基本查询_子查询(实验四)

    SQL基本查询_子查询(实验四) 1.查询所有员工中薪水低于"孙军"的员工姓名和薪水: 2.查询与部门编号为"01"的岗位相同的员工姓名.岗位.薪水及部门号: ...

  8. 599. Minimum Index Sum of Two Lists

    Suppose Andy and Doris want to choose a restaurant for dinner, and they both have a list of favorite ...

  9. js获取图片的EXIF,解决图片旋转问题

    相信大家在做项目的时候会遇到在canvas里加入图片时,图片发生90°,180°的旋转.当时的你肯定时懵逼的,为毛. 其实这就是图片的EXIF搞的鬼. 什么是EXIF 简单来说,Exif 信息就是由数 ...

  10. 仿知乎app登录界面(Material Design设计框架拿来就用的TexnInputLayout)

    在我脑子里还没有Material Design这种概念,就我个人而言,PC端应用扁平化设计必须成为首选,手当其冲的两款即时通讯旺旺和QQ早就完成UI扁平化的更新,然而客户端扁平化的设计本身就存在天生的 ...