JVM垃圾收集器

简介: JVM垃圾收集器

前言

最近被问到了JVM的垃圾收集器,在此进行整理记录,供大家一起学习。

jvm垃圾收集器

jvm垃圾收集器是jvm内存回收的具体实现。本次讨论hotspot虚拟机中的垃圾收集器。

图中总共有7中垃圾收集器。两个收集器中连线则表示可以配合使用。
中间的横线代表新生代和老年代的分区。上面的是新生代的垃圾收集器,下面是老年代的垃圾收集器。

serial收集器

serial收集器是最早的收集器,是单线程的垃圾收集器,采用复制收集算法。在他进行垃圾收集的时候,只会占用一个cpu或一个线程。垃圾收集时,必须暂停所有的用户线程,直到垃圾收集结束。
serial收集器的运行过程如下:

serial收集器是运行在client模式下的默认新生代收集器。简单而高效。

ParNew收集器

ParNew收集器是Serial收集器的多线程版本。除了多线程外,其他与serial收集器一摸一样。也是一款复制算法的收集器。
ParNew收集器的运行过程如下:

ParNew收集器是server模式下的虚拟机的首选垃圾收集器。ParNew收集器在单CPU环境下,效果没有serial收集器的效率高,还存在线程切换的开销。默认开启的线程数与CPU数量相等。可以使用-XX:ParallelGcThreads参数来限制收集的线程数。

Parallel Scavenge收集器

Parallel Scavenge收集器也采用复制算法,特点是该收集器关注吞吐量。吞吐量就是CPU用于运行用户代码的时间与CPU总消耗时间的比值。停顿时间越短就越适合与用户交互的程序。高吞吐量可以高效率的利用CPU时间,尽快完成程序运算。适合在后台运算,不需要太多的交互任务。

Parallel Scavenge收集器提供了两个参数用于精确控制吞吐量,分别是控制景大垃圾收集
停顿时间的-XX:MaxGCPauseMillis参数以及直接设置吞吐量大小的-XX:GCTimeRatio參数。
MaxGCPauseMillis参教允许的值是一个大于0的毫秒数,收集器将尽可能地保证内存回
收花费的时间不超过设定值。
不过大家不要认为如果把这个参数的值设置得很小,就能使
得系统的垃圾收集速度变得更快,GC停顿时间缩短是以牺牲吞吐量和新生代空间来换取的。
系统把新生代调小一点,收集300MB新生代肯定比收集500MB快,这也直接导致垃圾
收集发生得更频繁一些,原来10秒收集一次、每次停顿100毫秒,现在变成5秒收集一次、
每次停顿70毫秒。
停顿时间的确在下降,但吞吐量也降下来了。

GCTimeRatio参数的值应当是一个大于0且小于100的整数,也就是垃圾收集时间占总
时间的比率,相当于是吞吐量的倒数。如果把此参数设置为19,那允许的最大GC时间就占
总时间的5% (即1/<1+19)>,默认值为99。就是允许最大1%(即1 / (1+99))的垃圾收
集时间。
由于与吞吐量关系密切,Parallel Scavenge收集器也经常称为吞吐量优先收集器。

除上述两个参数之外,Parallel Scavenge收集器还有一个参数-XX:+UscAdaptiveSizePolicy
值得关注。这是一个开关参数,当这个参数打开之后,就不需要手工指定新生代的大
小-Xmn, Eden与Survivor区的比例(-XX:SurvivorRatio)、晋升老年代对象年龄
(-XX:pretenureSizeThreshold)等细节参数了,虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整参数。这种调节方式为自适应调节策略。

Serial Old收集器

Serial Old是Serial收集器的老年代版本,它同样是一个单线程收集器,使用“标记一
整理”算法。这个收集器的主要意义也是在于给Client模式下的虚拟机使用。如果在Server
模式下,那么它主要还有两大用途:一种用途是在JDK1.5以及之前的版本中与Parallel
Scavenge收集器搭配使用。另一种用途就是作为CMS收集器的后备预案,在并发收集发生
Concurrent Mode Failure时使用。这两点都将在后面的内容中详细讲解。
Serial Old收集器的运行过程如下:

Parallel Old收集器

Parallel Old是Parallel Scavenge收集器的老年代版本,使用多线程和“标记一整理”算
法。这个收集器是在JDK1.6中才开始提供的。
Parallel Old的运行过程如下

Cms收集器

CMS收集器是一种以获取最短回收停顿时间为目标的收集器。CMS收集器是基于"标记一清除”算法实现的。
运行过程分为四个步骤:
1、初始标记
2、并发标记
3、重新标记
4、并发清除
其中初始标记、重新标记这两个步骤仍是-Stop The World。初始标记只是标记GC Roots能直接关联到的对象,速度很快;
并发标记阶段进行GC Roots tracing的过程。而重新标记阶段则是为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段稍长一些,但远比并发标记的时间短。由于整个过程中耗时最长的并发标记和并发清除过程收集器线程都可以与用户线程一起工作,所以,从总体上来说,CMS收集器的内存回收过程是与用户线程一起并发执行的。
运行过程如下:

Cms有几个明显的缺点:
1、Cms收集器对cpu资源异常敏感。
2、Cms收集器无法处理浮动垃圾,可能出现Concurrent mode failure失败导致另一次gc的产生。
3、Cms标记清楚会产生内存垃圾。

G1收集器

G1是一款面向服务端应用的垃圾收集器。G1收集器具备如下特点。
1、并行与并发,G1能充分利用多CPU、多核环境下的硬件优势,使用多个CPU (CPU或者CPU核心)来缩短Stop The World停顿的时间,部分其他收集器原本需要停顿Java线程执行的GC动作,G1收集器仍然可以通过并发的方式让Java程序继续执行。
2、分代收集:与其他收集器一样,分代概念在G1中依然得以保留。虽然G1可以不需要其他收集器配合就能独立管理整个GC堆,但它能够釆用不同的方式去处理新创建的对象和已经存活了一段时间、熬过多次GC的旧对象以获取更好的收集效果。
3、空间整合:与CMS的“标记一清理”算法不同,G1从整体来看是基于“标记一整理”算法实现的收集器,从局部(两个Region之间)上来看是基于“复制”算法实现的,但无论如何,这两种算法都意味着G1运作期间不会产生内存空间碎片,收集后能提供规整的可用内存。这种特性有利于程序长时间运行,分配大对象时不会因为无法找到连续内存空间而提前触发下一次GC。
4、可预测的停顿:这是G1相对于CMS的另一大优势,降低停顿时间是G1和CMS共同的关注点,但G1除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为N毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒,这几乎已经是实时Java(RTSJ)的垃圾收集器的特征了。
在G1之前的其他收集器进行收集的范围都是整个新生代或者老年代,而G1不再是这样。使用G1收集器时,Java堆的内存布局就与其他收集器有很大差别,它将整个Java堆划
分为多个大小相等的独立区域(Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分Region (不需要连续)的集合。
G1收集器之所以能建立可预测的停顿时间模型,是因为它可以有计划地避免在整个Java堆中进行全区域的垃圾收集。
G1跟踪各个Region里面的垃圾堆积的价值大小,在后台维护一个优先列表,每次根据允许
的收集时间,优先回收价值最大的Region (这也就是Garbage-First名称的来由)。这种使用
Region划分内存空间以及有优先级的区域回收方式,保证了G1收集器在有限的时间内可以
获取尽可能高的收集效率。
G1收集器的运作过程如下:
1、初始标记
2、并发标记
3、最终标记
4、筛选回收

相关文章
|
2月前
|
存储 监控 算法
JVM调优深度剖析:内存模型、垃圾收集、工具与实战
【10月更文挑战第9天】在Java开发领域,Java虚拟机(JVM)的性能调优是构建高性能、高并发系统不可或缺的一部分。作为一名资深架构师,深入理解JVM的内存模型、垃圾收集机制、调优工具及其实现原理,对于提升系统的整体性能和稳定性至关重要。本文将深入探讨这些内容,并提供针对单机几十万并发系统的JVM调优策略和Java代码示例。
55 2
|
4月前
|
存储 算法 Java
JVM自动内存管理之垃圾收集算法
文章概述了JVM内存管理和垃圾收集的基本概念,提供一个关于JVM内存管理和垃圾收集的基础理解框架。
JVM自动内存管理之垃圾收集算法
|
4月前
|
存储 算法 Java
JVM组成结构详解:类加载、运行时数据区、执行引擎与垃圾收集器的协同工作
【8月更文挑战第25天】Java虚拟机(JVM)是Java平台的核心,它使Java程序能在任何支持JVM的平台上运行。JVM包含复杂的结构,如类加载子系统、运行时数据区、执行引擎、本地库接口和垃圾收集器。例如,当运行含有第三方库的程序时,类加载子系统会加载必要的.class文件;运行时数据区管理程序数据,如对象实例存储在堆中;执行引擎执行字节码;本地库接口允许Java调用本地应用程序;垃圾收集器则负责清理不再使用的对象,防止内存泄漏。这些组件协同工作,确保了Java程序的高效运行。
28 3
|
4月前
|
C# UED 开发者
WPF打印功能实现秘籍:从页面到纸张,带你玩转WPF打印技术大揭秘!
【8月更文挑战第31天】在WPF应用开发中,打印功能至关重要,不仅能提升用户体验,还增强了应用的实用性。本文介绍WPF打印的基础概念与实现方法,涵盖页面元素打印、打印机设置及打印预览。通过具体案例,展示了如何利用`PrintDialog`和`PrintDocument`控件添加打印支持,并使用`PrinterSettings`类进行配置,最后通过`PrintPreviewWindow`实现打印预览功能。
388 0
|
4月前
|
C# UED 开发者
WPF动画大揭秘:掌握动画技巧,让你的界面动起来,告别枯燥与乏味!
【8月更文挑战第31天】在WPF应用开发中,动画能显著提升用户体验,使其更加生动有趣。本文将介绍WPF动画的基础知识和实现方法,包括平移、缩放、旋转等常见类型,并通过示例代码展示如何使用`DoubleAnimation`创建平移动画。此外,还将介绍动画触发器的使用,帮助开发者更好地控制动画效果,提升应用的吸引力。
200 0
|
4月前
|
算法 Java 程序员
【JVM的秘密花园】揭秘垃圾收集器的神秘面纱!
【8月更文挑战第25天】在Java虚拟机(JVM)中,垃圾收集(GC)自动管理内存,回收未使用的对象以避免内存泄漏和性能下降。本文深入介绍了JVM中的GC算法,包括串行、并行、CMS及G1等类型及其工作原理。选择合适的GC策略至关重要:小型应用适合串行收集器;大型应用或多核CPU环境推荐并行收集器或CMS;需减少停顿时间时,CMS是好选择;G1适用于大堆且对停顿时间敏感的应用。理解这些能帮助开发者优化程序性能和稳定性。
37 0
|
4月前
|
算法 Java
JVM自动内存管理之垃圾收集器
这篇文章是关于Java虚拟机(JVM)自动内存管理中的垃圾收集器的详细介绍。
|
5月前
|
监控 算法 Java
深入理解Java虚拟机:垃圾收集机制的演变与最佳实践
【7月更文挑战第14天】本文将带领读者穿梭于JVM的心脏——垃圾收集器,探索其设计哲学、实现原理和性能调优。我们将从早期简单的收集算法出发,逐步深入到现代高效的垃圾收集策略,并分享一些实用的调优技巧,帮助开发者在编写和维护Java应用时做出明智的决策。
55 3
|
5月前
|
算法 Java
Java面试题:列举并解释JVM中常见的垃圾收集器,并比较它们的优缺点
Java面试题:列举并解释JVM中常见的垃圾收集器,并比较它们的优缺点
104 3
|
5月前
|
Java UED
Java面试题:描述JVM中垃圾收集的Stop-The-World现象及其影响
Java面试题:描述JVM中垃圾收集的Stop-The-World现象及其影响
57 1