Java虚拟机规范中对垃圾收集器应该如何实现并没有任何规定,因此不同的厂商,不同版本的虚拟机所提供的垃圾收集器可能会有很大差距.

 HotSpot虚拟机示意图:

  说明:两个收集器之间存在连线说明它们可以搭配使用.虚拟机所处的区域则表明它属于新生代收集器还是老年代收集器.

Serial收集器
  这个收集器是一个单线程收集器,但是它是"单线程"的意义,并不仅仅说明它只会使用一个CPU或一条收集器去完成垃圾收集工作,更重要的是它进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束.
  优点:简单而高效(与其他收集器的单线程相比),对于限定单个CPU的环境来说,Serial收集器由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程收集效率.   

ParNew收集器
  ParNew收集器起始就是Serial收集器的多线程版本.
  除了Serial收集器外,目前只有ParNew能与CMS收集器配合工作.

Parallel Scavenge收集器
  Parallel Scavenge收集器是一个新生代收集器,也是使用复制算法的收集器,又是并行的多线程收集器.
  Parallel Scavenge收集器的目标是达到一个可控制的吞吐量(Throughout).
  吞吐量就是CPU用于运行用户代码的时间与CPU消耗时间的比值.
  吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)

  停顿时间越短就越适合需要与用户交互的程序,良好的相应速度能提升用户体验,而吞吐量则可以高效率地利用CPU时间,尽快完成程序的运算任务,主要适合在后台运算而不需要太多交互的任务.

  Parallel Scavenge收集器提供了两个参数用于精确控制吞吐量,分别是控制最大对大垃圾收集停顿时间的-xx:MaxGCPauseMillis参数以及直接设置吞吐量大小的-xx:GCTimeRauo参数.

Serial Old收集器
  Serial Old 是Serial收集器的老年代版本,是一个单线程的收集器.使用"标记-整理"算法.
  两大用途:
  a)在JDK1.5以及之前的版本中与Parallel Scavenge收集器搭配使用.
  b) 作为CMS收集器的后备预案,在并发收集发生Concurrent Mode Failure 时使用.

Parallel Old收集器
  Parallel Old是Parallel Scavenge收集器的老年代版本,使用多线程和"标记-整理"算法.
  在注重吞吐量以及CPU资源敏感的场合,都可以优先考虑Parallel Scavenge加Parallel Old收集器.

CMS收集器
  CMS(Concurrent Mark Sweep)收集器是一种一获取最短回收停顿时间为目标的收集器.
  CMS收集器是基于"标记-清除"算法实现的,整个过程分为4个步骤(仍然需要"Stop The Word"):
  I.初始化标记(CMS Concurrent Mark)
  II.并发标记(CMS Concurrent Mark)
  III.重新标记(CMS Remark)
  IV.并发请求(CMS Concurrent Sweeep)

  初始化标记仅仅是标记一下GC Root能直接关联到的对象,速度很快,并发标记阶段是进行GC Root Tracing的过程,而重新标记阶段则是为了修正并发标记期间因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段稍长一些,但这远比并发标记的时间短.

  从总体上说,CMS收集器的内存回收过程是与用户线程一起并发执行的.

  缺点:
  I.CMS收集器对CPU资源非常敏感
  II.CMS收集器无法处理浮动垃圾(Floating Garbage),可能出现"Concurrent Mode Failure"失败而导致另一次Full GC的产生.
  III.CMS是基于"标记-清除"算法实现的收集器,意味着收集结束时会有大量的空间碎片产生.

G1收集器
  G1(Garbage-First)收集器是当今收集器是当今收集器技术发展的最前沿成果之一.
  G1是一款面向服务端应用的垃圾收集器,具备一下节点:
  I.并行与并发:G1能充分利用多CPU,多核环境下的硬件优势,使用多个CPU来缩短Stop_The_Word停顿的时间,部分其他收集器原本需要停顿Java线程执行的GC动作,G1收集器仍然可以通过并发的方式让Java程序继续执行.
  II.分代收集
  III.空间整合:G1从整体来看是基于"标记-整理"算法实现的收集器.从局部(两个Regin之间)上看是基于"复制"算法实现的,但是无论如何,这两种算法都意味着G1运行期间不会产生内存空间碎片,收集后能提供规整的可用内存.这种特性有利于程序长时间运行,分配大对象时不会因为无法找到连续空间而提前触发下一次GC.
  IV.可预测的停顿:这是G1相对于CMS的另一大优势,降低停顿时间是G1和CMS共同的关注点,但是G1除了追求低停顿外,还能建立可预测的时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒,这几乎已经是实时Java的垃圾收集器的特征了.

  使用G1收集器时,Java堆的内存布局就与其他收集器有很大差别,他将整个Java堆划分为多个大小相等的独立区域(Regin),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分Regin(不需要连续)的集合.

  G1收集器之所以能建立可预测的停顿时间模型,是因为它可以有计划地避免在整个Java堆中进行全区域的垃圾收集.G1跟踪各个Regin里面的垃圾堆积的价值大小,在后台维护一个有限列表,每次根据允许的收集时间,优化回收价值最大的Regin(这就是Garbage-First名称的由来).

  在G1收集器中.Regin之间的对象引用以及其他收集器中的新生代与老年代之间的对象引用,虚拟机都是使用Remenbered Set 来避免全堆扫描的.G1中每个Regin都有一个与之对应的Remenbered Set,虚拟机发现程序在对Reference类型的数据进行写操作时,会产生一个Write Barrier暂时中断写操作,检查Reference引用的对象是否处于不同的Regin之中(在分代的例子中就是检查是否老年代中的对象引用了新生代的对象).如果是,便通过CardTable把相关引用信息记录到被引用对象所属的Regin的Remenbered Set即可保证不对全堆扫描也不会有遗漏.

  G1收集器的运作大致可划分为一下几个步骤:
  I.初始化标记(Initial Marking)
  II.并发标记(Concurrent Marking)
  III.最终标记(Final Marking)
  IV. 筛选回收(Live Data Counting and Evacuation)

  初始标记阶段仅仅是标记一下GC Roots能直接关联到的对象,并且修改TAMS(Next Top at Mark Start)的值,让下一阶段用户程序并发运行时,能在正确可用的Regin中创建对象.这阶段需要停顿线程,但耗时很短.
  并发标记阶段是从GC Root 开始对堆中对象进行可达性分析,找出存活的对象,这阶段耗时较长,但可与用户进程并发执行.
  最终标记阶段则是为了修正在并发标记期间因用户程序继续执行运作导致标记产生变动的那一部分标记记录,虚拟机将这段时间对象变化记录在线程Remenbered Set Logs里面,最终标记阶段需要把Remenbered Set Logs的数据合并到Remenbered Set中,这个阶段需要停顿线程,但是可并行执行.
  筛选回收阶段首先对各个Regin的回收价值和成本进行排序,根据用户所期望的GC停顿时间来制定回收计划.这个阶段也可以做到与用户程序一起并发执行,但是因为回收一部分Regin,时间是用户可控制的,而且停顿用户线程将大幅度提高收集效率.

JVM-垃圾收集器的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. JVM垃圾收集器(1)

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

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

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

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

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

  10. JVM垃圾收集器

    JVM中垃圾的回收由垃圾收集器进行,随着JDK的不断升级,垃圾收集器也开发出了各种版本,垃圾收集器不断优化的动力,就是为了实现更短的停顿. 下面是7种不同的分代收集器,如果两个收集器之间有连线,则表示 ...

随机推荐

  1. phalcon(费尔康)框架学习笔记

    phalcon(费尔康)框架学习笔记 http://www.qixing318.com/article/phalcon-framework-to-study-notes.html 目录结构   pha ...

  2. Unity3D WebCamTexture 调用外部摄像头

    http://www.itnose.net/detail/6259004.html 一:Unity 中使用WebCamTexture 调用摄像头实现拍照和摄像. using UnityEngine; ...

  3. location.pathname;outline:medium;undefined不能加引号

    1. location.pathname -- 返回URL的域名后的部分.例如 http://www.dreamdu.com/xhtml/ 返回/xhtml/ 2. 判断某个名称为undefined时 ...

  4. redis.conf详解

    # Redis示例配置文件 # 注意单位问题:当需要设置内存大小的时候,可以使用类似1k.5GB.4M这样的常见格式: # # 1k => bytes # 1kb => bytes # 1 ...

  5. 【bzoj1037】生日聚会

    bzoj1037 题意 \(n\)个男孩,\(m\)个女孩,共\(n+m\)个排成一排. 要求对于任意连续的一段,男孩与女孩的数目之差不超过\(k\). 求排列的方案数. \(1\leq n,m\le ...

  6. MySQL中基本的多表连接查询教程

    一.多表连接类型1. 笛卡尔积(交叉连接) 在MySQL中可以为CROSS JOIN或者省略CROSS即JOIN,或者使用','  如: SELECT * FROM table1 CROSS JOIN ...

  7. is(C# 参考)

    检查对象是否与给定类型兼容. 例如,下面的代码可以确定对象是否为 MyObject 类型的一个实例,或者对象是否为从 MyObject 派生的一个类型:     if (obj is MyObject ...

  8. ARM字节对齐问题详解

    一.什么是字节对齐,为什么要对齐? 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这 ...

  9. PHP的那些坑

    1.urlencode urlencode编码的对象必须是utf-8编码.如果是其它格式的编码就会出现乱码. 2.array_merge 一般来说,array_merge就是把两个或两个以上的数组组合 ...

  10. C++调用父类的构造函数规则

    构造方法用来初始化类的对象,与父类的其它成员不同,它不能被子类继承(子类可以继承父类所有的成员变量和成员方法,但不继承父类的构造方法).因此,在创建子类对象时,为了初始化从父类继承来的数据成员,系统需 ...