Java虚拟机详解(四)------垃圾收集器

简介: Java虚拟机详解(四)------垃圾收集器目录 1、垃圾收集器种类2、Serial收集器3、ParNew收集器4、Parallel Scavenge收集器5、Serial Old收集器6、Parallel Old收集器7、CMS收集器8、G1收集器9、如何选择垃圾收集器  10、几个名词解释   上一篇博客我们介绍了Java虚拟机垃圾回收,介绍了几种常用的垃圾回收算法,包括标记-清除,标记整理,复制等,这些算法我们可以看做是内存回收的理论方法,那么在Java虚拟机中,由谁来具体实现这些方法呢?   没错,就是本篇博客介绍的内容——垃圾收集器。

Java虚拟机详解(四)------垃圾收集器

目录

1、垃圾收集器种类
2、Serial收集器
3、ParNew收集器
4、Parallel Scavenge收集器
5、Serial Old收集器
6、Parallel Old收集器
7、CMS收集器
8、G1收集器
9、如何选择垃圾收集器  
10、几个名词解释

  上一篇博客我们介绍了Java虚拟机垃圾回收,介绍了几种常用的垃圾回收算法,包括标记-清除,标记整理,复制等,这些算法我们可以看做是内存回收的理论方法,那么在Java虚拟机中,由谁来具体实现这些方法呢?

  没错,就是本篇博客介绍的内容——垃圾收集器。

回到顶部
1、垃圾收集器种类
  事实上Java虚拟机规范对垃圾收集器应该如何实现,并没有任何的规定,所以不同的厂商、不同版本的虚拟机所提供的垃圾收集器都会有所不同,并且一般都会提供参数供用户根据自己的应用特点和要求组合出各个年代所使用的收集器。

  下图是基于 Sun HotSpot 虚拟机1.6版 Update 22的虚拟机种类:

  

  由上图我们可以总结出几个结论:

  ①、新生代垃圾收集器:Serial、ParNew、Parallel Scavenge;

    老年代垃圾收集器:Serial Old(MSC)、Parallel Old、CMS;

    整堆垃圾收集器:G1

  ②、垃圾收集器之间的连线表示可以搭配使用,有如下几种组合:

    Serial/Serial Old、Serial/CMS、ParNew/Serial Old、ParNew/CMS、Parallel Scavenge/Serial Old、Parallel Scavenge/Parallel Old、G1;

  ③、串行收集器Serial:Serial、Serial Old

    并行收集器 Parallel:Parallel Scavenge、Parallel Old

    并发收集器:CMS、G1

  ps:对于文章中有一些名词不理解的,可以先看本篇博客最后一个小节。

回到顶部
2、Serial收集器
  这是一个最基本,历史最悠久的垃圾收集器,是JDK1.3之前新生代唯一的垃圾收集器。

  该收集器有如下特点:

  ①、作用于新生代

  由上图也可看出,这是一个新生代垃圾收集器,采用的垃圾回收算法是复制算法。

  ②、单线程

  工作时只会使用一个CPU或者一条收集线程去完成工作。

  ③、进行垃圾收集时,必须暂停所有工作线程

  也就是说使用Serial收集器进行垃圾回收时,别的工作线程都暂停,系统这时候会有卡顿现象产生。

  ④、适用场景

  Serial 收集器由于没有线程交互的开销,对于限定单个CPU的环境,可以获得最高的单线程收集效率。

  一般在用户的桌面场景中,分配给虚拟机管理的内存一般来说不会很大,收集几十兆或一两百兆的新生代,定顿时间可以控制在几十毫秒,只要不是频繁发生的,这点停顿是可以接受的。

  所以 Serial 收集器对于运行在 Client 模式下的虚拟机是一种很好的选择。

回到顶部
3、ParNew收集器
  这个收集器其实就是Serial收集器的多线程版本。

  也就是说其特点除了多线程,其余和Serial收集器一样,事实上,这两个收集器实现上也共用了很多代码。

  ①、作用于新生代

  一个新生代垃圾收集器,采用的垃圾回收算法是复制算法。

  ②、多线程

  弥补了Serial收集器单线程的缺陷。

  ③、适用场景

  由于其多线程的特性,是大多数运行在 Server 模式下的虚拟机首选新生代垃圾收集器。

  另外需要说明的是,能够与下面将要介绍的划时代垃圾收集器CMS(Concurrent Mark Sweep)配合使用,也是一个重要原因。

回到顶部
4、Parallel Scavenge收集器
  前面介绍的垃圾收集器关注点是尽可能缩小垃圾收集时的用户线程停顿时间。而 Parallel Scanvenge 收集器是为了达到一个可控制的吞吐量。

  吞吐量 = 运行用户代码的时间 / (运行用户代码的时间+垃圾收集时间)

  可以用下面两个参数进行精确控制:

  -XX:MaxGCPauseMills  设置最大垃圾收集停顿时间

  -XX:GCTimeRatio 设置吞吐量大小

  ①、作用于新生代

  一个新生代垃圾收集器,采用的垃圾回收算法是复制算法。

  ②、多线程

  并行的多线程垃圾收集器。

  ③、吞吐量

  这个收集器可以精确控制吞吐量。

  ④、适用场景

  设置垃圾收集停顿时间短适合需要与用户快速交互的程序;

  而设置高吞吐量可以最高效的利用CPU效率,尽快的完成程序的运算任务,主要适合在后台运算而不需要太多交互的任务。

回到顶部
5、Serial Old收集器
  Serial Old 收集器是 Serial 收集器的老年代版本,特点如下:

  ①、作用于老年代

  ②、单线程

  ③、使用标记-整理算法

  ④、进行垃圾收集时,必须暂停所有工作线程

回到顶部
6、Parallel Old收集器
  Parallel Old 是 Parallel Scavenge收集器的老年代版本,使用多线程和“标记-整理”算法。

  ①、作用于老年代

  ②、多线程

  ③、使用标记-整理算法

  除了具有以上几个特点,比较关键的是能和新生代收集器 Parallel Scavenge 配置使用,获得吞吐量最大化的效果。

回到顶部
7、CMS收集器
  CMS,全称为 Concurrent Mark Sweep ,顾名思义并发的,采用标记-清除算法。另外也将这个收集器称为并发低延迟收集器(Concurrent Low Pause Collector)

  这是一款跨时代的垃圾收集器,真正做到了垃圾收集线程与用户线程(基本上)同时工作。和 Serial 收集器的 Stop The World(妈妈打扫房间的时候,你不能再将垃圾丢到地上) 相比,真正做到了妈妈一边打扫房间,你一边丢垃圾。

  ①、作用于老年代

  ②、多线程

  ③、使用标记-清除算法

  整个算法过程分为如下 4 步:

  一、初始标记(CMS initial mark):只是仅仅标记GC Root 能够直接关联的对象,速度很快,但是需要“Stop The World”  

  二、并发标记(CMS concurrent mark):进行GC Root Tracing的过程,简单来说就是遍历Initial Marking阶段标记出来的存活对象,然后继续递归标记这些对象可达的对象。

  三、重新标记(CMS Remark):修正并发标记期间,因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,需要“Stop The World”。这个时间一般比初始标记长,但是远比并发标记时间短。

  四、并发清除(CMS concurrent sweep):对上一步标记的对象进行清除操作。

  由于整个过程最耗时的操作是第二(并发标记)、四步(并发清除),而这两步垃圾收集器线程是可以和用户线程一起工作的。所以整体来说,CMS垃圾收集和用户线程是一起并发的执行的。

  缺点:

  ①、对CPU资源敏感

  因为在并发阶段,会占用一部分CPU资源,从而导致应用程序变慢,总吞吐量会降低。

  ②、产生浮动垃圾

  由于CMS并发清理阶段用户线程还在工作,这个时候产生的垃圾,CMS无法在本次收集中处理掉它们,只能留在下一次GC时再将其处理掉,这部分垃圾称为“浮动垃圾”。

  ③、产生内存垃圾碎片

  因为采用的算法是标记-清除,很明显,会有空间碎片产生。

回到顶部
8、G1收集器
  这是当前收集器技术发展的最前沿的成果。可以实现在基本不牺牲吞吐量的前提下完成低停顿的内存回收。

  这是因为它并不像前面介绍的所有垃圾收集器是区分新生代,老年代的,它作用于全区域。将整个Java堆划分为多个大小固定的独立区域(Regin),并且跟踪这些区域的垃圾堆积面积,在后台维护一个优先级列表,每次根据允许的收集时间,优先回收垃圾最多的区域,这样保证了G1收集器在有限的时间内可以获得最高的收集效率。

  它与前面讲的 CMS 垃圾收集器相比,有两个显著的改进:

  ①、采用 标记-整理 的回收算法

  这样不会产生空间碎片

  ②、可以精确的控制停顿时间

  能让使用者明确指定一个长度为M毫秒的时间片内,消耗在垃圾回收上的时间不超过 N 毫秒。

  ③、作用于整个Java堆

  G1收集器不区分年轻代和老年代,是整堆垃圾收集器。

回到顶部
9、如何选择垃圾收集器  
  详细文档可以查看官方介绍,如下

  https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/collectors.html

  这里我们翻译一下结论:

  除非应用程序有相当严格的暂停时间要求,否则就让JVM自己选择垃圾收集器。并且可以适当优先调整堆的大小来提高性能。如果还不满足要求,则以下面四点作为指导:

  1. 如果应用程序内存小于100M,那么使用选项选择串行收集器-XX:+UseSerialGC。

  2. 如果应用程序将在单核处理器上运行,并且没有停顿时间的要求,选择串行-XX:+UseSerialGC或者 JVM 自己选

  3. 如果允许停顿时间超过1秒,选择并行或 JVM 自己选

  4. 如果响应时间比总吞吐量更重要,并且垃圾收集暂停必须保持短于大约1秒,则使用-XX:+UseConcMarkSweepGC或选择并发收集器-XX:+UseG1GC。

回到顶部
10、几个名词解释
  ①、并行

  指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。

  适合科学计算、后台处理等弱交互场景。

  ②、并发

  指用户线程与垃圾收集器线程同时执行(但不一定是并行的,可能会交替执行),用户线程继续执行,而垃圾收集线程运行在另一块CPU上。

  适合对响应快速的场景,比如Web。

  ③、停顿时间

  垃圾收集器做垃圾回收中断应用执行的时间。

  ④、吞吐量

   吞吐量 = 运行用户代码的时间 / (运行用户代码的时间+垃圾收集时间)

作者:YSOcean
出处:http://www.cnblogs.com/ysocean/

目录
打赏
0
0
0
0
48
分享
相关文章
|
1月前
|
JVM—垃圾收集算法和HotSpot算法实现细节
JVM的垃圾收集算法和HotSpot的实现细节复杂但至关重要,通过理解和掌握这些算法,可以为Java应用程序选择合适的垃圾收集器,并进行有效的性能调优。选择适当的垃圾收集策略,结合合理的内存配置和日志分析,能够显著提升应用的运行效率和稳定性。
59 15
Java内存管理:深入理解垃圾收集器
在Java的世界里,内存管理是一块基石,它支撑着应用程序的稳定运行。本文将带你走进Java的垃圾收集器(GC),探索它是如何默默守护着我们的内存安全。我们将从垃圾收集的基本概念出发,逐步深入到不同垃圾收集器的工作机制,并通过实例分析它们在实际应用中的表现。文章不仅旨在提升你对Java内存管理的认识,更希望你能通过这些知识优化你的代码,让程序运行更加高效。
79 3
Java内存管理:垃圾收集器的工作原理与调优实践
在Java的世界里,内存管理是一块神秘的领域。它像是一位默默无闻的守护者,确保程序顺畅运行而不被无用对象所困扰。本文将带你一探究竟,了解垃圾收集器如何在后台无声地工作,以及如何通过调优来提升系统性能。让我们一起走进Java内存管理的迷宫,寻找提高应用性能的秘诀。
云原生之旅:从容器到微服务的演进之路Java 内存管理:垃圾收集器与性能调优
【8月更文挑战第30天】在数字化时代的浪潮中,企业如何乘风破浪?云原生技术提供了一个强有力的桨。本文将带你从容器技术的基石出发,探索微服务架构的奥秘,最终实现在云端自由翱翔的梦想。我们将一起见证代码如何转化为业务的翅膀,让你的应用在云海中高飞。
Java内存管理深度剖析:从垃圾收集到内存泄漏的全面指南####
本文深入探讨了Java虚拟机(JVM)中的内存管理机制,特别是垃圾收集(GC)的工作原理及其调优策略。不同于传统的摘要概述,本文将通过实际案例分析,揭示内存泄漏的根源与预防措施,为开发者提供实战中的优化建议,旨在帮助读者构建高效、稳定的Java应用。 ####
70 8
深入探索Java虚拟机(JVM)的内存管理机制
本文旨在为读者提供对Java虚拟机(JVM)内存管理机制的深入理解。通过详细解析JVM的内存结构、垃圾回收算法以及性能优化策略,本文不仅揭示了Java程序高效运行背后的原理,还为开发者提供了优化应用程序性能的实用技巧。不同于常规摘要仅概述文章大意,本文摘要将简要介绍JVM内存管理的关键点,为读者提供一个清晰的学习路线图。
Java虚拟机(JVM)的内存管理与性能优化
本文深入探讨了Java虚拟机(JVM)的内存管理机制,包括堆、栈、方法区等关键区域的功能与作用。通过分析垃圾回收算法和调优策略,旨在帮助开发者理解如何有效提升Java应用的性能。文章采用通俗易懂的语言,结合具体实例,使读者能够轻松掌握复杂的内存管理概念,并应用于实际开发中。
JVM调优深度剖析:内存模型、垃圾收集、工具与实战
【10月更文挑战第9天】在Java开发领域,Java虚拟机(JVM)的性能调优是构建高性能、高并发系统不可或缺的一部分。作为一名资深架构师,深入理解JVM的内存模型、垃圾收集机制、调优工具及其实现原理,对于提升系统的整体性能和稳定性至关重要。本文将深入探讨这些内容,并提供针对单机几十万并发系统的JVM调优策略和Java代码示例。
102 2
Java Z 垃圾收集器如何彻底改变内存管理
大家好,我是V哥。今天聊聊Java的ZGC(Z Garbage Collector)。ZGC是一个低延迟垃圾收集器,专为大内存应用场景设计。其核心优势包括:极低的暂停时间(通常低于10毫秒)、支持TB级内存、使用着色指针实现高效对象管理、并发压缩和去碎片化、不分代的内存管理。适用于实时数据分析、高性能服务器和在线交易系统等场景,能显著提升应用的性能和稳定性。如何启用?只需在JVM启动参数中加入`-XX:+UseZGC`即可。
181 0
深入解析 Java 虚拟机:内存区域、类加载与垃圾回收机制
本文介绍了 JVM 的内存区域划分、类加载过程及垃圾回收机制。内存区域包括程序计数器、堆、栈和元数据区,每个区域存储不同类型的数据。类加载过程涉及加载、验证、准备、解析和初始化五个步骤。垃圾回收机制主要在堆内存进行,通过可达性分析识别垃圾对象,并采用标记-清除、复制和标记-整理等算法进行回收。此外,还介绍了 CMS 和 G1 等垃圾回收器的特点。
180 0
深入解析 Java 虚拟机:内存区域、类加载与垃圾回收机制
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等