JVM--JVM经典垃圾收集器整理(Serial收集器、ParNew收集器、Parallel Scavenge收集器、Garbage First收集器、Z

简介: - 1、Serial收集器- 2、ParNew收集器- 3、Parallel Scavenge收集器- 4、Serial Old收集器- 5、Parallel Old收集器

参考资料列表:

注:本文说的垃圾收集器基本都是JDK1.7以后的垃圾收集器,不讨论JDK1.7以前的。

经典垃圾收集器盘点

  • 1、Serial收集器
  • 2、ParNew收集器
  • 3、Parallel Scavenge收集器
  • 4、Serial Old收集器
  • 5、Parallel Old收集器
  • 6、CMS收集器
  • 7、Garbage First收集器
  • 8、Shenandoah收集器
  • 9、ZGC收集器
  • 10、Epsilon收集器

Serial收集器

Serial收集器是最基础、历史最悠久的收集器,曾经(在JDK1.3.1之前)是HotSpot虚拟机新生代收集器的唯一选择,时至今日,垃圾收集器的不断改进,不断出新,Serial依然在我们的垃圾收集器的选项里面。

Serial收集器运行示意图

在这里插入图片描述

Serial收集器的特点:

  • 优点:简单高效,拥有很高的单线程收集效率
  • 缺点:收集过程需要暂停所有线程
  • 使用算法:复制算法
  • 适用范围:新生代
  • 应用:Client模式下的默认新生代收集器
对于Serial收集器缺点有一个比较有意思的故事:Serial收集器的运行过程需要暂停应用程序所有线程(Stop The World),它带给用户的恶劣体验。早期HotSpot虚拟机的设计者们表示完全理解,但也同时表示非常委屈:“你妈妈在给你打扫房间的时候,肯定也会让你老老实实地在椅子上或者房间外待着,如果她一边打扫,你一边乱扔纸屑,这房间还能打扫完?”这确实是一个合情合理的矛盾,虽然垃圾收集这项工作听起来和打扫房间属于一个工种,但实际上肯定还要比打扫房间复杂得多!(现在的垃圾收集器一样需要停顿,只是都做到了毫秒级)

使用该垃圾收集器 -XX:+UseSerialGC

使用之前我们可以去查看一下,当前虚拟机是否使用的Serial,如果是我们不需要去更改,如果不是则添加参数:-XX:+UseSerialGC。更改完成之后,我们输出一下jvm参数,可以看到如下图输出。
在这里插入图片描述

ParNew收集器

ParNew收集器实质上是Serial收集器的多线程并行版本

ParNew收集器运行示意图

在这里插入图片描述

ParNew收集器的特点:

  • 优点:在多CPU时,比Serial效率高。
  • 缺点:收集过程暂停所有应用程序线程,单CPU时比Serial效率差。
  • 使用算法:复制算法
  • 适用范围:新生代
  • 应用:运行在Server模式下的虚拟机中首选的新生代收集器

使用ParNew收集器 -XX:+UseParNewGC

在这里插入图片描述

Parallel Scavenge收集器

Parallel Scavenge收集器也是一款新生代收集器,它同样是基于标记-复制算法实现的收集器,也是能够并行收集的多线程收集器……Parallel Scavenge的诸多特性从表面上看和ParNew非常相似,Parallel Scavenge收集器的特点是它的关注点与其他收集器不同,CMS等收集器的关注点是尽可能地缩短垃圾收集时用户线程的停顿时间,而Parallel Scavenge收集器的目标则是达到一个可控制的吞吐量(Throughput)。所谓吞吐量就是处理器用于运行用户代码的时间与处理器总消耗时间的比值。

  • 吞吐量 = 运行用户代码时间/运行用户代码时间 + 运行垃圾收集器时间。
  • 比如虚拟机总共运行了100分钟,垃圾收集时间用了1分钟,吞吐量=(100-1)/100=99%。
  • 若吞吐量越大,意味着垃圾收集的时间越短,则用户代码可以充分利用CPU资源,尽快完成程序的运算任务。

吞吐量我们可以自行控制?

吞吐量我们从上面的描述可以看到,他是一个比值。那么我们自然能够通过调整比值的参数来影响吞吐量。主要涉及的命令有一下两个

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

根据吞吐量对应的计算公式我们可以看到,当我们的垃圾收集停顿时间变短的时候(垃圾收集停顿是一个大于0的毫秒数),我们的吞吐量在增大。不过大家不要异想天开地认为如果把这个参数的值设置得更小一点就能使得系统的垃圾收集速度变得更快,当我们把这个参数设置的更小的时候,它对应的能够有效收集的时间或者空间会变小。假若停顿时间为100ms能够收集500M的堆空间,那么50ms能够收集的空间可能会低于250M的堆空间。 垃圾收集器的有效工作时间变短,收集垃圾的效率并不一定提高,同时对应的也只能相对的调整我们的吞吐量。

使用Parallel Scavenge收集器 -XX:+UseParallelGC

在这里插入图片描述

Serial Old收集器

Serial Old是Serial收集器的老年代版本,它同样是一个单线程收集器,使用标记-整理算法。这个收集器的主要意义也是供客户端模式下的HotSpot虚拟机使用。

Serial Old收集器运行示意图

在这里插入图片描述

Parallel Old收集器

Parallel Old收集器是Parallel Scavenge收集器的老年代版本,使用多线程和"标记-整理算法"进行垃圾回收。

CMS收集器

CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。它的运作过程相对于前面几种收集器来说要更复杂一些,整个过程分为四个步骤,包括:

  • 1)初始标记(CMS initial mark)
  • 2)并发标记(CMS concurrent mark)
  • 3)重新标记(CMS remark)
  • 4)并发清除(CMS concurrent sweep)
由于整个过程中,并发标记和并发清除,收集器线程可以与用户线程一起工作,所以总体上来
说,CMS收集器的内存回收过程是与用户线程一起并发地执行的。

CMS收集器特点:

  • 优点:并发收集、低停顿
  • 缺点:产生大量空间碎片、并发阶段会降低吞吐量

CMS收集器运行示意图

在这里插入图片描述

使用CMS收集器 -XX:+UseConcMarkSweepGC

Garbage First收集器

Garbage First(简称G1)收集器是垃圾收集器技术发展历史上的里程碑式的成果,它是一款主要面向服务端应用的垃圾收集器

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

G1收集器的运作过程大致可划分为以下四个步骤:

  • 初始标记(Initial Marking)
  • 并发标记(Concurrent Marking)
  • 最终标记(Final Marking)
  • 筛选回收(Live Data Counting and Evacuation)

判断是否需要使用G1收集器?

  • (1)50%以上的堆被存活对象占用
  • (2)对象分配和晋升的速度变化非常大
  • (3)垃圾回收时间比较长

使用Garbage First收集器 -XX:+UseG1G

目录
相关文章
|
2月前
|
存储 监控 算法
JVM调优深度剖析:内存模型、垃圾收集、工具与实战
【10月更文挑战第9天】在Java开发领域,Java虚拟机(JVM)的性能调优是构建高性能、高并发系统不可或缺的一部分。作为一名资深架构师,深入理解JVM的内存模型、垃圾收集机制、调优工具及其实现原理,对于提升系统的整体性能和稳定性至关重要。本文将深入探讨这些内容,并提供针对单机几十万并发系统的JVM调优策略和Java代码示例。
60 2
|
4月前
|
存储 算法 Java
JVM组成结构详解:类加载、运行时数据区、执行引擎与垃圾收集器的协同工作
【8月更文挑战第25天】Java虚拟机(JVM)是Java平台的核心,它使Java程序能在任何支持JVM的平台上运行。JVM包含复杂的结构,如类加载子系统、运行时数据区、执行引擎、本地库接口和垃圾收集器。例如,当运行含有第三方库的程序时,类加载子系统会加载必要的.class文件;运行时数据区管理程序数据,如对象实例存储在堆中;执行引擎执行字节码;本地库接口允许Java调用本地应用程序;垃圾收集器则负责清理不再使用的对象,防止内存泄漏。这些组件协同工作,确保了Java程序的高效运行。
34 3
|
4月前
|
C# UED 开发者
WPF打印功能实现秘籍:从页面到纸张,带你玩转WPF打印技术大揭秘!
【8月更文挑战第31天】在WPF应用开发中,打印功能至关重要,不仅能提升用户体验,还增强了应用的实用性。本文介绍WPF打印的基础概念与实现方法,涵盖页面元素打印、打印机设置及打印预览。通过具体案例,展示了如何利用`PrintDialog`和`PrintDocument`控件添加打印支持,并使用`PrinterSettings`类进行配置,最后通过`PrintPreviewWindow`实现打印预览功能。
463 0
|
4月前
|
C# UED 开发者
WPF动画大揭秘:掌握动画技巧,让你的界面动起来,告别枯燥与乏味!
【8月更文挑战第31天】在WPF应用开发中,动画能显著提升用户体验,使其更加生动有趣。本文将介绍WPF动画的基础知识和实现方法,包括平移、缩放、旋转等常见类型,并通过示例代码展示如何使用`DoubleAnimation`创建平移动画。此外,还将介绍动画触发器的使用,帮助开发者更好地控制动画效果,提升应用的吸引力。
238 0
|
4月前
|
算法 Java 程序员
【JVM的秘密花园】揭秘垃圾收集器的神秘面纱!
【8月更文挑战第25天】在Java虚拟机(JVM)中,垃圾收集(GC)自动管理内存,回收未使用的对象以避免内存泄漏和性能下降。本文深入介绍了JVM中的GC算法,包括串行、并行、CMS及G1等类型及其工作原理。选择合适的GC策略至关重要:小型应用适合串行收集器;大型应用或多核CPU环境推荐并行收集器或CMS;需减少停顿时间时,CMS是好选择;G1适用于大堆且对停顿时间敏感的应用。理解这些能帮助开发者优化程序性能和稳定性。
39 0
|
28天前
|
缓存 Prometheus 监控
Elasticsearch集群JVM调优设置合适的堆内存大小
Elasticsearch集群JVM调优设置合适的堆内存大小
232 1
|
2月前
|
存储 安全 Java
jvm 锁的 膨胀过程?锁内存怎么变化的
【10月更文挑战第3天】在Java虚拟机(JVM)中,`synchronized`关键字用于实现同步,确保多个线程在访问共享资源时的一致性和线程安全。JVM对`synchronized`进行了优化,以适应不同的竞争场景,这种优化主要体现在锁的膨胀过程,即从偏向锁到轻量级锁,再到重量级锁的转变。下面我们将详细介绍这一过程以及锁在内存中的变化。
43 4
|
18天前
|
存储 监控 算法
深入探索Java虚拟机(JVM)的内存管理机制
本文旨在为读者提供对Java虚拟机(JVM)内存管理机制的深入理解。通过详细解析JVM的内存结构、垃圾回收算法以及性能优化策略,本文不仅揭示了Java程序高效运行背后的原理,还为开发者提供了优化应用程序性能的实用技巧。不同于常规摘要仅概述文章大意,本文摘要将简要介绍JVM内存管理的关键点,为读者提供一个清晰的学习路线图。
|
27天前
|
Java
JVM内存参数
-Xmx[]:堆空间最大内存 -Xms[]:堆空间最小内存,一般设置成跟堆空间最大内存一样的 -Xmn[]:新生代的最大内存 -xx[use 垃圾回收器名称]:指定垃圾回收器 -xss:设置单个线程栈大小 一般设堆空间为最大可用物理地址的百分之80
|
28天前
|
Java
JVM运行时数据区(内存结构)
1)虚拟机栈:每次调用方法都会在虚拟机栈中产生一个栈帧,每个栈帧中都有方法的参数、局部变量、方法出口等信息,方法执行完毕后释放栈帧 (2)本地方法栈:为native修饰的本地方法提供的空间,在HotSpot中与虚拟机合二为一 (3)程序计数器:保存指令执行的地址,方便线程切回后能继续执行代码
21 3