深入理解JVM--垃圾收集器

你未必出类拔萃,但一定与众不同

垃圾收集器

垃圾收集器

  • 垃圾收集器
      • Serial收集器
      • ParNew收集器
      • Parallel Scavenge收集器
      • Serial Old收集器
      • Parallel Old收集器
      • CMS收集器
      • G1收集器(Garbage First)

如果说收集算法是内存回收的方法论,那垃圾收集器就是内存回收的实践者。

深入理解JVM--垃圾收集器_第1张图片

以上是七种作用于不同分代的收集器,如果两个收集器之间存在连线,就说他们可以搭配使用,而图中所处于的区域则表示是属于新生代还是老年代收集器

Serial收集器

Serial收集器是最基础,历史最悠久的收集器,这个收集器是一个单线程工作的收集器,

而“单线程”不是指它会使用一个收集器或一条收集线程去完成垃圾收集工作,更重要的是强调他在进行垃圾收集工作的时候,必须暂停其他所有工作线程,直到收集结束(Stop the World)

深入理解JVM--垃圾收集器_第2张图片

目前依旧是HotSpot虚拟机运行在客户端模式下的默认新生代收集器

  • 简单而高效,对于内存资源受限的环境,它是所有收集器里额外内存消耗最小的
  • 对于单核处理器或者处理器核心数较少的环境来说,Serial收集器由于没有线程交互的开销,专心做垃圾收集自然可以获得更高的单线程收集效率

ParNew收集器

ParNew收集器则是Serial收集器的多线程并行版本

深入理解JVM--垃圾收集器_第3张图片

ParNew收集器除了支持多线程并行收集之外,其他与Serial收集器相比并没有太多创新之处,但是却是不少运行咋服务端模式下的HotSpot首选的新生代收集器

一个很重要的原因就是 除了Serial收集器外,目前只有他能够和CMS收集器配合工作。

注意 并行和并发

并行:描述的是多条垃圾收集器线程之间的关系,说明同一时间有多条这样的线程在协同工作,通常默认此用户线程是等待状态

并发: 并发描述的是垃圾收集器线程与用户线程之间的关系,说明同一时间垃圾收集器线程与用户线程都在运行。

Parallel Scavenge收集器

Parallel Scavenge收集器也是一款新生代收集器,同样是基于-标记复制算法实现的收集器,也是能够并行收集的多线程收集器

特点

关注点与其他收集器不同,Parallel Scavenge收集器目标是达到一个可以控制的吞吐量

吞吐量就是处理器用于运行用户代码的时间与处理器总消耗时间的比值。

Parallel Scavenge收集器提供了两个参数用于精确控制吞吐量

  • 控制最大垃圾收集停顿时间的-XX:MaxGCPauseMillis参数
  • 直接设置吞吐量大小的-XX:GCTimeRatio参数

由于与吞吐量关系密切,Parallel Scavenge收集器也被称为吞吐量优先收集器

Serial Old收集器

Serial Old是Serial收集器的老年代版本,同样是一个单线程收集器

主要意义也是供客户端模式下的HotSpot虚拟机使用,而在服务端下则两种用途

  • 在JDK5以及之前的版本与Parallel Scavenge收集器搭配使用
  • 作为CMS收集器发生失败的备选方案

深入理解JVM--垃圾收集器_第4张图片

Parallel Old收集器

Parallel Old是Parallel Scavenge收集器的老年代版本,支持线程并发收集,基于标记整理算法

JDK6以后才开始提供这个收集器

在注重吞吐量或者处理器资源较为稀缺的场合都可以考虑Parallel Scavenge收集器+Parallel Old收集器组合

Parallel Old收集器工作过程如图

深入理解JVM--垃圾收集器_第5张图片

CMS收集器

CMS收集器是一种以获取最短回收停顿时间为目标的收集器。

较为关注服务的响应速度,希望系统的停顿时间尽可能的短,以给用户带来更好的交互体验。

总共分为四个步骤

  • 初始标记
  • 并发标记
  • 重新标记
  • 并发清除

其中初始标记和重新标记依旧需要Stop the World

初始标记:标记GC Roots能直接关联到的对象,速度很快

并发标记:从GC Roots的直接关联对象开始遍历整个对象图的过程,过程很长但是不需要停顿用户线程,与垃圾收集器一起并发运行

重新标记:为了修正并发标记期间,用户线程运行时产生变动的一部分对象的标记记录

并发清除:清除掉被标记的对象,与用户线程并发运行

深入理解JVM--垃圾收集器_第6张图片

CMS收集器默认启动的回收线程数是(处理器核心数量+3)/4,也就是说处理器核心在四个以上,并发回收时垃圾收集只占用不超过25%的处理器运算资源。

FULL GC 问题

CMS无法处理浮动垃圾,有可能失败进(Concurrent Mode Failure)而导致另一次完全的“Stop the World”的Full GC的产生

在CMS的并发标记和并发清理是,用户线程是持续运行的,程序自然就有新的垃圾对象产生,这一部分在标记过程结束以后,CMS无法在档当次的垃圾回收过程去解决他们,只好等待下次的垃圾回收。这一部分就是浮动垃圾

因此需要预留一部分内存空间供并发收集时的程序运行

G1收集器(Garbage First)

G1收集器是垃圾收集器技术发展历史上的里程碑式的成果

开创了收集器面向局部收集的设计思路和基于Region的内存布局形式

G1不再坚持固定大小以及固定数量的分代区域划分,而是把连续的Java堆划分为多个大小相等的独立区域Region 每一个Region都可以扮演新生代的Eden空间,Survivor空间或者老年代空间,收集器根据不同的扮演角色的Region采用不同的策略去处理。

Region还有一类特殊的Humongous区域,用来收集大对象,只要对象的大小超过了一个Region的一半大小就会判定为大对象。

G1收集器的运行过程分为四个步骤

  • 初始标记
  • 并发标记
  • 最终标记
  • 筛选回收

初始标记:仅仅只是标记一下GC Roots能够直接关联到的对象,并且修改TAMS指针的值,让下一阶段用户线程并发运行时,能够正确地在可用的Region中分配新对象,这个阶段需要停顿线程,但耗时很短,而且是借助Minor GC同步完成

并发标记:从GC ROOT开始对堆中对象进行可达性分析,扫描堆的对象图,找出需要回收的对象,对象图扫描完成后,还需要重新处理SATB记录下的并发有引用变动的对象

最终标记:对用户线程最另一个短暂的暂停,用于处理并发阶段结束后遗留下来的少量STAB记录

筛选回收:负责更新Region的统计数据,对各个Region的回收价值和成本进行排序,根据用户期望的停顿时间来指定回收计划,自由选择多个任意的Region构成回收集合。把决定回收的Region的存活对象复制到空的Region中,然后清除掉旧的Region的全部空间,这里必须暂停用户线程,由多条收集器线程并行完成。

除了并发标记外,其他的步骤都需要Stop the World。

你可能感兴趣的:(笔记,jvm,java)