深入浅出JVM(十二)之垃圾回收算法

简介: 深入浅出JVM(十二)之垃圾回收算法

上篇文章深入浅出JVM(十一)之如何判断对象“已死”已经深入浅出的解析JVM是如何评判对象不再使用,不再使用的对象将变成“垃圾”,等待回收

垃圾回收算法有多种,适用于不同的场景,不同的垃圾收集器使用不同的算法

本篇文章将围绕垃圾回收算法,深入浅出的解析垃圾回收分类以及各种垃圾回收算法

垃圾回收算法

垃圾回收分类

垃圾收集器有着多种GC方式,不同的GC方式有自己的特点,回收的堆内存部分也不同

堆内存分为新生代和老年代,新生代存储“年轻”的对象,老年代存储“老”或内存大的对象,对象年龄由经历多少次GC来判断

其中整堆收集时不仅会回收整个堆还会回收元空间(直接内存)

  • 部分收集(Partial GC): 收集目标是部分空间
  • 新生代收集(Minor GC/ Young GC):收集新生代Eden、Survive to、Survive from区
  • 老年代收集(MajorGC/Old GC):收集老年代
  • 混合收集(Mixed GC):收集整个新生代和部分老年代
  • 整堆收集(Full GC): 整个堆 + 元空间

标记-清除算法

Mark-Sweep

标记:从GCRoots开始遍历引用链,标记所有可达对象 (在对象头中标记)

清除:从堆内存开始线性遍历,发现某个对象没被标记时对它进行回收

image.png

标记-清除算法实现简单、不需要改变引用地址,但是需要两次遍历扫描效率不高,并且会出现内存碎片

注意:这里的清除并不是真正意义上的回收内存,只是更新空闲列表(标记这块内存地址为空闲,后续有新对象需要使用就覆盖)

复制算法

Copying

Survive区分为两块容量一样的Survive to区和Survive from区

每次GC将Eden区和Survive from区存活的对象放入Survive to区,此时Survive to区改名为Survive from区,原来的Survive from区改名为Survive to区 保证Survive to区总是空闲的

如果Survive from区的对象经过一定次数的GC后(默认15次),把它放入老年代

流程图

注意:图中的dean为Eden区(写错)

image.png

image.png

注意:最终的survive from区存活对象占用的内存应该是(那两块蓝色)挨着一起的,图中为了标识字分开来了

复制算法不需要遍历,并且不会产生内存碎片,但是会浪费survive区一半的内存,移动对象时需要STW暂停用户线程,并且复制后会改变引用地址(hotspot使用直接指针访问,还要改变栈中reference执行新引用地址)

如果复制算法中对象存活率太高会导致十分消耗资源,因此一般只有新生代才使用复制算法

标记-整理算法

Mark-Compact

标记:从GCRoots开始遍历引用链,标记所有可达对象(在对象头中标记) (与标记-清除算法一致)

整理:让所有存活对象往内存空间一端移动,然后直接清理掉边界以外的所有内存

image.png

标记-整理算法不会出现内存碎片也不会浪费空间,但是效率低(比标记-清除还多了整理功能),移动对象导致STW和改变reference指向

如果不移动对象会产生内存碎片,内存碎片过多,将无法为大对象分配内存

还有种方法:多次标记-清除,等内存碎片多了再进行标记-整理

分代收集算法

标记清除mark-sweep 复制copying 标记整理mark-compact
速度
GC后是否需要移动对象 不移动对象 移动对象 移动对象
GC后是否存在内存碎片 存在内存碎片 不存在内存碎片 不存在内存碎片

需要移动对象 意味着 要改变改对象引用地址 也就是说要改变栈中reference指向改对象的引用地址,并且会发生STW停顿用户线程

当空间中存在大量内存碎片时,可能导致大对象无法存储

分代收集算法 : 对待不同生命周期的对象可以采用不同的回收算法(不同场景采用不同算法)

年轻代: 对象生命周期短、存活率低、回收频繁,采用复制算法,高效

老年代: 对象生命周期长、存活率高、回收没年轻代频繁,采用标记-清除 或混用 标记-整理

增量收集算法

mark-sweep、copying、mark-compact算法都存在STW,如果垃圾回收时间很长,会严重影响用户线程的响应

增量收集算法: 采用用户线程与垃圾收集线程交替执行

增量收集算法能够提高用户线程的响应时间,但存在GC、用户线程切换的开销,降低了吞吐量,GC成本变大

分区算法

堆空间越大,GC时间就会越长,用户线程响应就越慢

分区算法: 将堆空间划分为连续不同的区,根据要求的停顿时间合理回收n个区,而不是一下回收整个堆

每个区独立使用,独立回收,根据能承受的停顿时间控制一次回收多少个区

G1收集器以及两块低延迟收集器Shenandoah、ZGC就使用到这种分区算法

总结

本篇文章围绕垃圾回收算法,深入浅出解析垃圾回收分类、标记清除、复制、标记整理、分代收集、增量收集、分区算法等多种算法

从垃圾回收空间上划分可以分为Full GC回收整个堆加上元空间、Minor GC回收新生代、major GC回收老年代、mixed GC回收新生代加老年代

标记清除算法会遍历引用链标记可达对象从而清理不可达对象,会产生内存碎片,速度一般

复制算法不会产生内存碎片,并且速度很快,但是会浪费survivor区一半空间,并且会移动对象

标记整理算法在标记清理基础上增加整理功能,不会产生内存碎片,但会移动对象,速度慢

不同的算法有不同的特点,应对新生代可以使用复制算法,应对老年代可以使用标签清除/整理算法

增量收集使用GC、用户线程交替执行,虽然降低用户响应,但线程切换、吞吐量下降会增加GC成本

分区算法将堆内存划分为多个区,根据能够接收的停顿时间来回收性价比高的多个区,停顿时间既在能够接收时间内,又能够回收性能比高的区

最后(一键三连求求拉~)

本篇文章将被收入JVM专栏,觉得不错感兴趣的同学可以收藏专栏哟~

本篇文章笔记以及案例被收入 gitee-StudyJavagithub-StudyJava 感兴趣的同学可以stat下持续关注喔~

有什么问题可以在评论区交流,如果觉得菜菜写的不错,可以点赞、关注、收藏支持一下~

关注菜菜,分享更多干货,公众号:菜菜的后端私房菜

目录
打赏
0
0
0
0
63
分享
相关文章
JVM实战—4.JVM垃圾回收器的原理和调优
本文详细探讨了JVM垃圾回收机制,包括新生代ParNew和老年代CMS垃圾回收器的工作原理与优化方法。内容涵盖ParNew的多线程特性、默认线程数设置及适用场景,CMS的四个阶段(初始标记、并发标记、重新标记、并发清理)及其性能分析,以及如何通过合理分配内存区域、调整参数(如-XX:SurvivorRatio、-XX:MaxTenuringThreshold等)来优化垃圾回收。此外,还结合电商大促案例,分析了系统高峰期的内存使用模型,并总结了YGC和FGC的触发条件与优化策略。最后,针对常见问题进行了汇总解答,强调了基于系统运行模型进行JVM参数调优的重要性。
JVM实战—4.JVM垃圾回收器的原理和调优
JVM简介—2.垃圾回收器和内存分配策略
本文介绍了Java垃圾回收机制的多个方面,包括垃圾回收概述、对象存活判断、引用类型介绍、垃圾收集算法、垃圾收集器设计、具体垃圾回收器详情、Stop The World现象、内存分配与回收策略、新生代配置演示、内存泄漏和溢出问题以及JDK提供的相关工具。
JVM简介—2.垃圾回收器和内存分配策略
JVM实战—3.JVM垃圾回收的算法和全流程
本文详细介绍了JVM内存管理与垃圾回收机制,涵盖以下内容:对象何时被垃圾回收、垃圾回收算法及其优劣、新生代和老年代的垃圾回收算法、Stop the World问题分析、核心流程梳理。
JVM实战—3.JVM垃圾回收的算法和全流程
Java虚拟机(JVM)的垃圾回收机制深度解析####
本文深入探讨了Java虚拟机(JVM)的垃圾回收机制,旨在揭示其背后的工作原理与优化策略。我们将从垃圾回收的基本概念入手,逐步剖析标记-清除、复制算法、标记-整理等主流垃圾回收算法的原理与实现细节。通过对比不同算法的优缺点及适用场景,为开发者提供优化Java应用性能与内存管理的实践指南。 ####
|
29天前
|
JVM—垃圾收集算法和HotSpot算法实现细节
JVM的垃圾收集算法和HotSpot的实现细节复杂但至关重要,通过理解和掌握这些算法,可以为Java应用程序选择合适的垃圾收集器,并进行有效的性能调优。选择适当的垃圾收集策略,结合合理的内存配置和日志分析,能够显著提升应用的运行效率和稳定性。
55 15
|
4月前
|
Java虚拟机(JVM)垃圾回收机制深度剖析与优化策略####
本文作为一篇技术性文章,深入探讨了Java虚拟机(JVM)中垃圾回收的工作原理,详细分析了标记-清除、复制算法、标记-压缩及分代收集等主流垃圾回收算法的特点和适用场景。通过实际案例,展示了不同GC(Garbage Collector)算法在应用中的表现差异,并针对大型应用提出了一系列优化策略,包括选择合适的GC算法、调整堆内存大小、并行与并发GC调优等,旨在帮助开发者更好地理解和优化Java应用的性能。 ####
103 0
JVM实战—5.G1垃圾回收器的原理和调优
本文详细解析了G1垃圾回收器的工作原理及其优化方法。首先介绍了G1通过将堆内存划分为多个Region实现分代回收,有效减少停顿时间,并可通过参数设置控制GC停顿时长。接着分析了G1相较于传统GC的优势,如停顿时间可控、大对象不进入老年代等。还探讨了如何合理设置G1参数以优化性能,包括调整新生代与老年代比例、控制GC频率及避免Full GC。最后结合实际案例说明了G1在大内存场景和对延迟敏感业务中的应用价值,同时解答了关于内存碎片、Region划分对性能影响等问题。
【JVM】——GC垃圾回收机制(图解通俗易懂)
GC垃圾回收,标识出垃圾(计数机制、可达性分析)内存释放机制(标记清除、复制算法、标记整理、分代回收)
Java虚拟机(JVM)垃圾回收机制深度解析与优化策略####
本文旨在深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法及参数调优方法。通过剖析垃圾回收的生命周期、内存区域划分以及GC日志分析,为开发者提供一套实用的JVM垃圾回收优化指南,助力提升Java应用的性能与稳定性。 ####
|
5月前
|
Java虚拟机垃圾回收机制深度剖析与优化策略####
【10月更文挑战第21天】 本文旨在深入探讨Java虚拟机(JVM)中的垃圾回收机制,揭示其工作原理、常见算法及参数调优技巧。通过案例分析,展示如何根据应用特性调整GC策略,以提升Java应用的性能和稳定性,为开发者提供实战中的优化指南。 ####
70 5
AI助理

你好,我是AI助理

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