热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

深入浅析JVM垃圾回收机制与收集器概述

本文基于《深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)》的阅读心得进行整理,详细探讨了JVM的垃圾回收机制及其各类收集器的特点与应用场景。通过分析不同垃圾收集器的工作原理和性能表现,帮助读者深入了解JVM内存管理的核心技术,为优化Java应用程序提供实用指导。

作品标明出处:本文是对《深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)》阅读后的整理,有兴趣的同学可购买正版进行学习!


1.查看JVM默认垃圾收集器

java -XX:+PrintCommandLineFlags -version

上图中的 -XX:+UseParallelGC就是我们默认使用的收集器,新生代使用的是Parallel Scanvenge收集器,老年代使用的是Serial Old


2.JVM垃圾收集器常用参数

 


3.垃圾收集器

 如果两个收集器之间存在连线,就说明它们可以搭配使用 ,图中收集器所处的区域,则表示它是属于新生代收集器抑或是老年代收集器


  •  Serial收集器

新生代收集器,低延迟

单线程收集器:不仅仅是说明它只会使用一个处理器或一条收集线程去完成垃圾收集工作,更重要的是强调在它进行垃圾收集时,必须暂停其他所有工作线程,直到它收集结束,Stop The World!


  •  ParNew收集器

新生代收集器

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

只有它能和CMS收集器搭配使用。

ParNew收集器是激活CMS后(使用-XX:+UseConcMarkSweepGC选项)的默认新生代收集器,也可以使用-XX:+/-UseParNewGC选项来强制指定或者禁用它。


  •  Parallel Scanvenge收集器

新生代收集器,标记--复制算法

和ParNew收集器非常相似,目标是达到一个可控制的吞吐量

 参数 -XX:+UseAdaptiveSizePolicy,垃圾收集的自适应调节策略,不需要人工指定新生代的大小(-Xmn)、Eden与Survivor区的比例(-XX:SurvivorRatio)、晋升老年代对象大小(-XX:PretenureSizeThreshold)等细节参数了,虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或者最大的吞吐量


  • Serial Old收集器

老年代单线程收集器,标记--整理算法

两种用途:

        1、在JDK 5以及之前的版本中与Parallel Scavenge收集器搭配使用 

        2、作为CMS收集器发生失败时的后备预案,在并发收集发生Concurrent Mode Failure时使用

.


  •  Parallel Old收集器

老年代多线程收集器,标记--整理算法

Parallel Scavenge + Parallel Old收集器搭配使用,吞吐量优先


  •  CMS收集器(Concurrent Mark Sweep)

老年代多线程收集器,标记--清除算法(收集结束可能会导致大量空间碎片,触发Full GC)

并发收集、低延迟,“并发低停顿收集器”(Concurrent Low Pause Collector)

整个过程分为四个步骤:

        1、初始标记(CMS initial mark)
        2、并发标记(CMS concurrent mark)
        3、重新标记(CMS remark)
        4、并发清除(CMS concurrent sweep)

 JDK5默认启动阈值为老年代使用了 68%,

JDK6时默认阈值提升至92%,此时可能导致CMS运行期间预留的内存无法满足程序分配新对象的需要,就会出现一次“并发失败”(Concurrent Mode Failure),这时候虚拟机将不得不启动后备预案:冻结用户线程的执行,临时启用Serial Old收集器来重新进行老年代的垃圾收集


  • G1(Garbage First)收集器

面向整个堆空间多线程收集器,标记--整理算法,每个Region又是基于标记--复制算法

低延迟、

JDK9以后默认垃圾收集器

面向局部收集、基于Region内存布局

面向堆内存任何部分来组成回收集,衡量标准为哪块内存中存放的垃圾最多,会后收益最大,这就是G1收集器的Mixed GC模式

G1把连续的Java堆划分为多个大小相等的独立区域Region,每个Region都可以根据需要,扮演新生代的Eden空间、Survivor空间,或者老年代空间;Region中还有一类特殊的Humongous区域,专门用来存储大对象。G1认为只要大小超过了一个Region容量一半的对象即可判定为大对象

每个Region大小可以通过参数-XX:G1HeapRegionSize设定,取值范围为1MB~32MB,且应为2的N次幂

而对于那些超过了整个Region容量的超级大对象,将会被存放在N个连续的Humongous Region之中,G1的大多数行为都把Humongous Region作为老年代的一部分来进行看待

 Region里面存在的跨Region引用对象如何解决?

 答:使用记忆集避免全堆作为GC Roots扫描,每个Region都维护有自己的记忆集,这些记忆集会记录下别的Region指向自己的指针,并标记这些指针分别在哪些卡页的范围之内。

由于Region数量比传统收集器的分代数量明显要多得多,因此G1收集器要比其他的传统垃圾收集器有着更高的内存占用负担。根据经验,G1至少要耗费大约相当于Java堆容量10%至20%的额外内存来维持收集器工作

G1收集器的四个步骤:

        1、初始标记(Initial Marking)

        2、并发标记(Concurrent Marking)

        3、最终标记(Final Marking)

        4、筛选回收(Live Data Counting and Evacuation)


  •  Shenandoah收集器

低延迟、并发收集,标记--整理算法

也是基于Region的堆内存布局,同样有着用于存放大对象的Humongous Region,默认的回收策略也同样是优先处理回收价值最大的Region

Shenandoah(目前)是默认不使用分代收集,不会有专门的新生代Region或者老年代Region的存在,没有实现分代

Shenandoah摒弃了在G1中耗费大量内存和计算资源去维护的记忆集,改用名为“连接矩阵”(ConnectionMatrix)的全局数据结构来记录跨Region的引用关系,降低了处理跨代指针时的记忆集维护消耗,也降低了伪共享问题的发生概率

Shenandoah收集器的工作过程大致可以划分为以下九个阶段:

        1、初始标记(Initial Marking)

        2、并发标记(Concurrent Marking)

        3、最终标记(Final Marking)

        4、并发清理(Concurrent Cleanup)

        5、并发回收(Concurrent Evacuation)

        6、初始引用更新(Initial Update Reference)

        7、并发引用更新(Concurrent Update Reference)

        8、最终引用更新(Final Update Reference)

        9、并发清理(Concurrent Cleanup)


  • ZGC

低延迟垃圾收集器,基于Region内存布局,并发标记-整理算法

ZGC的Region具有动态性——动态创建和销毁

在x64硬件平台下,ZGC的Region可以具有如图3-19所示的大、中、小三类容量:
        1、小型Region(Small Region):容量固定为2MB,用于放置小于256KB的小对象。
        2、中型Region(Medium Region):容量固定为32MB,用于放置大于等于256KB但小于4MB的对象。
        3、大型Region(Large Region):容量不固定,可以动态变化,但必须为2MB的整数倍,用于放置4MB或以上的大对象。每个大型Region中只会存放一个大对象

 ZGC收集器的运作过程:

        1、并发标记(Concurrent Mark)

        2、并发预备重分配(Concurrent Prepare for Relocate)

        3、并发重分配(Concurrent Relocate)

        4、并发重映射(Concurrent Remap)



推荐阅读
  • 本指南从零开始介绍Scala编程语言的基础知识,重点讲解了Scala解释器REPL(读取-求值-打印-循环)的使用方法。REPL是Scala开发中的重要工具,能够帮助初学者快速理解和实践Scala的基本语法和特性。通过详细的示例和练习,读者将能够熟练掌握Scala的基础概念和编程技巧。 ... [详细]
  • 如何利用Java 5 Executor框架高效构建和管理线程池
    Java 5 引入了 Executor 框架,为开发人员提供了一种高效管理和构建线程池的方法。该框架通过将任务提交与任务执行分离,简化了多线程编程的复杂性。利用 Executor 框架,开发人员可以更灵活地控制线程的创建、分配和管理,从而提高服务器端应用的性能和响应能力。此外,该框架还提供了多种线程池实现,如固定线程池、缓存线程池和单线程池,以适应不同的应用场景和需求。 ... [详细]
  • Squaretest:自动生成功能测试代码的高效插件
    本文将介绍一款名为Squaretest的高效插件,该工具能够自动生成功能测试代码。使用这款插件的主要原因是公司近期加强了代码质量的管控,对各项目进行了严格的单元测试评估。Squaretest不仅提高了测试代码的生成效率,还显著提升了代码的质量和可靠性。 ... [详细]
  • 本文深入解析了Java 8并发编程中的`AtomicInteger`类,详细探讨了其源码实现和应用场景。`AtomicInteger`通过硬件级别的原子操作,确保了整型变量在多线程环境下的安全性和高效性,避免了传统加锁方式带来的性能开销。文章不仅剖析了`AtomicInteger`的内部机制,还结合实际案例展示了其在并发编程中的优势和使用技巧。 ... [详细]
  • 尽管我们尽最大努力,任何软件开发过程中都难免会出现缺陷。为了更有效地提升对支持部门的协助与支撑,本文探讨了多种策略和最佳实践,旨在通过改进沟通、增强培训和支持流程来减少这些缺陷的影响,并提高整体服务质量和客户满意度。 ... [详细]
  • 求助:在CentOS 5.8系统上安装PECL扩展遇到问题
    在 CentOS 5.8 系统上尝试安装 APC 扩展时遇到了问题,具体表现为 PECL 工具无法正常工作。为了确保顺利安装,需要解决 PECL 的相关依赖和配置问题。建议检查 PHP 和 PECL 的版本兼容性,并确保所有必要的库和开发工具已正确安装。此外,可以尝试手动下载 APC 扩展的源代码并进行编译安装,以绕过 PECL 工具的限制。 ... [详细]
  • 在Android 4.4系统中,通过使用 `Intent` 对象并设置动作 `ACTION_GET_CONTENT` 或 `ACTION_OPEN_DOCUMENT`,可以从相册中选择图片并获取其路径。具体实现时,需要为 `Intent` 添加相应的类别,并处理返回的 Uri 以提取图片的文件路径。此方法适用于需要从用户相册中选择图片的应用场景,能够确保兼容性和用户体验。 ... [详细]
  • 动态壁纸 LiveWallPaper:让您的桌面栩栩如生(第二篇)
    在本文中,我们将继续探讨如何开发动态壁纸 LiveWallPaper,使您的桌面更加生动有趣。作为 2010 年 Google 暑期大学生博客分享大赛 Android 篇的一部分,我们将详细介绍 Ed Burnette 的《Hello, Android》第三版中的相关内容,并分享一些实用的开发技巧和经验。通过本篇文章,您将了解到如何利用 Android SDK 创建引人入胜的动态壁纸,提升用户体验。 ... [详细]
  • 投融资周报 | Circle 达成 4 亿美元融资协议,唯一艺术平台 A 轮融资超千万美元 ... [详细]
  • TypeScript 实战分享:Google 工程师深度解析 TypeScript 开发经验与心得
    TypeScript 实战分享:Google 工程师深度解析 TypeScript 开发经验与心得 ... [详细]
  • STAR: 转录组数据分析中的高效比对工具介绍
    欢迎关注“生信修炼手册”!STAR 是一款专为 RNA-seq 数据设计的高效比对工具,以其卓越的速度和高灵敏度著称。该软件在处理大规模转录组数据时表现出色,能够显著提高比对效率和准确性。此外,GATK 推荐使用 STAR 进行预处理步骤,以确保后续分析的可靠性。 ... [详细]
  • 在处理高并发场景时,确保业务逻辑的正确性是关键。本文深入探讨了Java原生锁机制的多种细粒度实现方法,旨在通过使用数据的时间戳、ID等关键字段进行锁定,以最小化对系统性能的影响。文章详细分析了不同锁策略的优缺点,并提供了实际应用中的最佳实践,帮助开发者在高并发环境下高效地实现锁机制。 ... [详细]
  • 本文详细探讨了MySQL数据库实例化参数的优化方法及其在实例查询中的应用。通过具体的源代码示例,介绍了如何高效地配置和查询MySQL实例,为开发者提供了有价值的参考和实践指导。 ... [详细]
  • HBase Java API 进阶:过滤器详解与应用实例
    本文详细探讨了HBase 1.2.6版本中Java API的高级应用,重点介绍了过滤器的使用方法和实际案例。首先,文章对几种常见的HBase过滤器进行了概述,包括列前缀过滤器(ColumnPrefixFilter)和时间戳过滤器(TimestampsFilter)。此外,还详细讲解了分页过滤器(PageFilter)的实现原理及其在大数据查询中的应用场景。通过具体的代码示例,读者可以更好地理解和掌握这些过滤器的使用技巧,从而提高数据处理的效率和灵活性。 ... [详细]
  • 技术分享:深入解析GestureDetector手势识别机制
    技术分享:深入解析GestureDetector手势识别机制 ... [详细]
author-avatar
青岛新侨妙妙
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有