前两篇《JVM入门——运行时数据区》《JVM常见垃圾回收算法》所提到的实际上JVM规范以及常用的垃圾回收算法,具体的JVM实现实际上不止一种,有JRockit、J9等待,当然最有名当属HotSpot JVM。下面是HotSpot JVM的整体架构图,本文着重介绍HotSpot中的垃圾回收器(Garbage Collector)。

  现有的HotSpot垃圾回收器以及之间的关系和应用范围如下图所示:

  其中G1 GC非常显眼的处于新生代和老年代之间,可以猜测这个G1 GC可同时运用在新生代和老年代,确实可以说G1是一个划时代新概念GC。

  在介绍上面的垃圾回收器之前要先说明JVM虚拟机的Client模式和Server模式,Java所能做的事一是做客户端简单说就是GUI桌面应用程序,二是可以用作服务器端。两种模式Client模式启动快,启动后性能较差,Server模式启动慢,启动后性能较高。

Serial GC(-XX:+UseSerialGC,复制算法,新生代

  这是一个比较古老的垃圾收集器,我理解它为“简单粗暴”,简单粗暴的方法往往可以应对简单的环境,事实上Serial GC在Client模式下正是如此。它是一个串行的垃圾收集器,串行意味着就算是有多核处理器也不会有多个线程来并行回收,在串行的同时,其它的正常工作线程也要停止工作,称为“Stop the world”。这实际很好理解,你在清扫垃圾的时候,总不希望有人同时在丢垃圾吧。当然Serial GC在如今的HotSpot JVM中Server模式下已经几乎废弃。另外,它工作使用垃圾回收的“复制算法”工作在Java堆的新生代。

ParNew GC-XX:+UseParNewGC复制算法新生代

  ParNew GC实际上是Serial GC的多线程版本。上面提到了Serial GC即使是多核CPU的环境下也是单线程进行垃圾内存的回收。此垃圾收集器侧可以做到多线程环境下进行垃圾内存的回收,这个多线程也仅仅是垃圾回收的多线程,而不是与用户线程并发执行。并且只有它能与CMS老年代的垃圾回收器配合使用,而CMS又恰恰是划时代意义的垃圾回收器,所以当JVM的老年代垃圾回收器是CMS的话,新生代的垃圾回收器通常是ParNew GC。

Parallel GC(-XX:+UseParallelGC,复制算法,新生代)

  它有点和ParaNew GC类似,从名字上来看也是并行的多线程收集器。我们之前提到过,在进行GC的过程中要“Stop the world”,停顿时间越短当然越好,很多垃圾回收器(包括前两个)关注的就是如何提高停顿时间。而Parallel GC关注的则是吞吐量。它关注的是垃圾回收的整体耗时,如果垃圾回收所占用的整体耗时较短,则吞吐量高,CPU就能将越多的时间用于任务的执行上,(吞吐量 = 任务运行时间 / (任务运行时间 + 垃圾回收时间))。

Serial Old GC(-XX:+UseSerialOldGC,标记-压缩算法,老年代)

  它是Serial GC的老年代版本,同样也是单线程,也能与Parallel GC配合使用作为它的老年代GC。

Parallel Old GC(-XX:+UseParallelOldGC,标记-压缩算法,老年代)

  为了避免如果在新生代选择了Parallel GC而老年代则只有选择Serial Old GC的困境,出现了Parallel GC的老年代版本——Parallel Old GC。故如果在一些需要高吞吐量的常量利用Parallel GC和Parallel Old GC组合将会是一个很好的选择。

☆Concurrent Mark Sweep(CMS) GC (-XX:+UseConcMarkSweepGC,标记-清除算法,老年代)

  CMS GC几乎占据着JVM老年代垃圾收集器的半壁江山,它划时代的意义就是垃圾回收线程几乎能用户线程做到同时工作。“几乎”是因为它还是不能做到完全不需要“Stop the world”,只是它尽可能的缩短了停顿时间。

它的整个垃圾回收过程可分为以下4个步骤:

  1. 初始标记
  2. 并发标记
  3. 重新标记
  4. 并发清理

  这4个步骤“初始标记”和“重新标记”需要进行短暂的“Stop the world”,并发标记的过程实际上就是和用户线程同时工作,也就是“一边丢垃圾,一边打扫”,这样就会带来一个问题,如果垃圾的产生是在标记后发生,那么这次垃圾就只有等到下次再回收。当然等到标记完了过后垃圾自然不会和用户线程产生冲突,而清理过程就能和用户线程同时处理了。对于此垃圾回收器有一个比较显著且不可避免的一个问题就是它所采用的是“标记-清除”算法,也就是说它不同会压缩存活的对象,这样就会带来内存空间碎片化的问题,如果出现需要分配一个连续的较大的内存空间则只能触发一次Full GC。上一篇《》中谈到了在新生代的垃圾回收称为“Minor GC”,老年代的垃圾回收称为“Major GC”,而“Full GC”则是在整个堆上触发一次垃圾回收,可想而知代价会相当高,而且此时不得不暂停用户线程,只能针对具体使用场景通过调整CMS GC的参数对其进行调整优化。

Garbage-First(G1) GC(-XX:+UseG1GC)

  G1 GC较之前所有的垃圾回收器都不同,从开头的第二幅图就能看出,它涵盖了新生代和老年代,或者说仅仅是从逻辑上还保留“新生代”和“老年代”这种说法,实际上它已不存在内存分代,它在JDK6中仅仅是实验版,在JDK7u4过后才正式商用,对于此垃圾回收器我将会单独对其讲解,另外它的论文地址在:http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.63.6386&rep=rep1&type=pdf

Hotspot JVM垃圾回收器的更多相关文章

  1. JVM 垃圾回收器工作原理及使用实例介绍(转载自IBM),直接复制粘贴,需要原文戳链接

    原文 https://www.ibm.com/developerworks/cn/java/j-lo-JVMGarbageCollection/ 再插一个关于线程和进程上下文,待判断 http://b ...

  2. Jvm垃圾回收器(终结篇)

    知识回顾: 第一篇<Jvm垃圾回收器(基础篇)>主要讲述了判断对象的生死?两种基础判断对象生死的算法.引用计数法.可达性分析算法,方法区的回收.在第二篇<Jvm垃圾回收器(算法篇)& ...

  3. Jvm垃圾回收器(算法篇)

    在<Jvm垃圾回收器(基础篇)>中我们主要学习了判断对象是否存活还是死亡?两种基础的垃圾回收算法:引用计数法.可达性分析算法.以及Java引用的4种分类:强引用.软引用.弱引用.虚引用.和 ...

  4. 【转】Java学习---垃圾回收算法与 JVM 垃圾回收器综述

    [原文]https://www.toutiao.com/i6593931841462338062/ 垃圾回收算法与 JVM 垃圾回收器综述 我们常说的垃圾回收算法可以分为两部分:对象的查找算法与真正的 ...

  5. 垃圾回收算法与 JVM 垃圾回收器综述(转)

    垃圾回收算法与 JVM 垃圾回收器综述 我们常说的垃圾回收算法可以分为两部分:对象的查找算法与真正的回收方法.不同回收器的实现细节各有不同,但总的来说基本所有的回收器都会关注如下两个方面:找出所有的存 ...

  6. JVM基础系列第9讲:JVM垃圾回收器

    前面文章中,我们介绍了 Java 虚拟机的内存结构,Java 虚拟机的垃圾回收机制,那么这篇文章我们说说具体执行垃圾回收的垃圾回收器. 总的来说,Java 虚拟机的垃圾回收器可以分为四大类别:串行回收 ...

  7. JVM垃圾回收器原理及使用介绍

    JVM垃圾回收器原理及使用介绍 垃圾收集基础 引用计数法(Reference Counting) 标记-清除算法(Mark-Sweep) 复制算法(Copying) 标记-压缩算法(Mark-Comp ...

  8. [Inside HotSpot] Serial垃圾回收器 (二) Minor GC

    Serial垃圾回收器Minor GC 1. DefNewGeneration垃圾回收 新生代使用复制算法做垃圾回收,比老年代的标记-压缩简单很多,所有回收代码都位于DefNewGeneration: ...

  9. JVM垃圾回收器理论分析与详解【纯理论】

    继续上次[https://www.cnblogs.com/webor2006/p/10740084.html]的理论继续..有点吐血的感觉,都不知道学了这么一大堆理论有何实际意义,本身JVM就是个理论 ...

随机推荐

  1. mxnet:结合R与GPU加速深度学习(转)

    近年来,深度学习可谓是机器学习方向的明星概念,不同的模型分别在图像处理与自然语言处理等任务中取得了前所未有的好成绩.在实际的应用中,大家除了关心模型的准确度,还常常希望能比较快速地完成模型的训练.一个 ...

  2. SparkR安装部署及数据分析实例

    1. SparkR的安装配置 1.1.       R与Rstudio的安装 1.1.1.           R的安装 我们的工作环境都是在Ubuntu下操作的,所以只介绍Ubuntu下安装R的方法 ...

  3. Nagios配置安装详解

    nagios.html :first-child{margin-top:0!important}img.plugin{box-shadow:0 1px 3px rgba(0,0,0,.1);borde ...

  4. sql导出

    第一步: 要求:把Library里面的Readers表导出到MyDB中(注意:读者编号.设置了主键)

  5. 一天搞定CSS: 浮动(float)与inline-block的区别--11

    浮动: 使元素脱离文档流,按照指定的方向发生移动,遇到父级的边界或者相邻的浮动元素就会停下来. inline-block: inline-block是指行内块元素,它具有行内元素和块元素两者的特点,可 ...

  6. javaSE_Java第一周总结:有难度题目集合

    第一周练习总结 说明:尽量采用多种做法解决 1.使用三种方法实现变量交换 public class Test1Change{ public static void main(String[] args ...

  7. Node.js爬虫-爬取慕课网课程信息

    第一次学习Node.js爬虫,所以这时一个简单的爬虫,Node.js的好处就是可以并发的执行 这个爬虫主要就是获取慕课网的课程信息,并把获得的信息存储到一个文件中,其中要用到cheerio库,它可以让 ...

  8. 【原创】源码角度分析Android的消息机制系列(一)——Android消息机制概述

    ι 版权声明:本文为博主原创文章,未经博主允许不得转载. 1.为什么需要Android的消息机制 因为Android系统不允许在子线程中去访问UI,即Android系统不允许在子线程中更新UI. 为什 ...

  9. Bash中的特殊变量和位置参量

    位置参量:向脚本或函数传递的参数,可以被set命令设置.重置和清空. 1.$$ 当前Shell的PID 2.$- 当前Shell的选项,如果是交互式shell,应该包含字符i,例如$ echo $-h ...

  10. 几个常用的linux命令(操作服务器时会用到)

    目录 tmux 背景 安装 使用 启动一个tmux session 暂时离开当前session 回到之前的session 重命名session 创建window 创建pane ps scp 参考 tm ...