JVM 垃圾回收相关算法介绍及图示

简介: JVM 垃圾回收相关算法介绍及图示

微信截图_20220523211416.png

概要:当成功区分出内存中存活对象和死亡对象后,GC接下来的任务就是执行垃圾回收,释放掉无用对象所占用的内存空间,以便有足够的可用内存空间为新对象分配内存。目前在JVM中比较常见的三种垃圾收集算法是:标记一清除算法(Mark-Sweep)复制算法(copying)标记-压缩算法(Mark-Compact)


封面地点:湖南省永州市蓝山县舜河村


作者:用心笑*😀


一、标记-清除算法


标记-清扫式垃圾回收器是一种直接的全面停顿算法。简单的说,它们找出所有不可达的对象,并将它们放入空闲列表Free。


标记:


标记的过程其实就是,遍历所有的GC Roots,然后将所有GC Roots可达的对象标记为存活的对象。


如下图:


微信截图_20220523211933.png


清除:


清除的过程将遍历堆中所有的对象,将没有标记的对象全部清除掉。


微信截图_20220523212020.png


这里所谓的清除并不是真的置空,而是把需要清除的对象地址保存在空闲的地址列表里。下次有新对象需要加载时,判断垃圾的位置空间是否够,如果够,就存放覆盖原有的地址。


  • 如果内存规整


  • 采用指针碰撞的方式进行内存分配


  • 如果内存不规整


  • 虚拟机需要维护一个列表


  • 空闲列表分配


优点:优点就是简单理解,容易实现。内存消耗较小。


缺点:1)需要扫描整个堆区,时间开销较大,效率不算高;2) 进行GC 时,会停止用户程序,而又因为时间开销大,所以对用户体验较差;3) 此方式清理出来的空间内存,可能是不连续,这就可能会产生内碎片(操作系统方面知识),就需要再维护一个空列表。


二、标记-复制算法


2.1、概述:


为了解决标记 - 清除算法在垃圾收集效率方而的缺陷M.L.Minsky于1963 年发表了著名的论文, “ 使用双存储区的Lisp语言垃圾收集器CA LISP Garbage CoIIector Algorithm Using SeriaI Secondary Storage 。M.L.Minsky 在该论文中描述的算法被人们称为复制(copying) 算法, 它也被M.L.Minsky 本人成功地引入到了Lisp语言的一个实现版本中。


GC复制算法原理是把内存分为两个空间一个是From空间,一个是To空间,对象一开始只在From空间分配,To空间是空闲的。GC时把存活的对象从From空间复制粘贴到To空间,之后把To空间变成新的From空间,原来的From空间变成To空间。回收前后对比下图所示


2.2、图示


微信截图_20220523212338.png


应用场景:目前JVM大都使用在新生代的垃圾回收中。


2.3、优缺点


对于任意的GC算法我们都可以从吞吐量(GC延迟),内存的分配效率,内存碎片化,堆的使用效率这个几个方面评估。


优点


  • GC复制算法只搜索并复制存活的对象,少了访问整堆和构造空闲链表的操作能够在短时间内完成GC。换言之,GC复制的吞吐量要比标记-清除要优秀,并且堆越大这种差距越明显。


  • 内存的分配效率:GC复制算法不使用空闲链表,因为分块本身就是一个连续的空间。只要新建的对象不超过剩余空间的大小,只需要移动指针即可~。所以GC复制算法的分配效率非常的高效


  • 复制过去以后保证空间的连续性,不会出现“碎片”问题。


缺点


  • 此算法的缺点也是很明显的,就是需要两倍的内存空间。


  • 复制而不是移动,意味着GC需要维护两块内存之间对象引用关系,不管是内存占用或者时间开销也不小


2.4、注意


复制算法还有一个情况:如果系统中的垃圾对象很多,复制算法需要复制的存活对象数量并不会太大,或者说非常低才行(老年代大量的对象存活,那么复制的对象将会有很多,效率会很低),所以复制算法大都是应用在新生代中的垃圾回收。


三、标记-整理算法(标记-压缩算法)


3.1、概述


复制算法的高效性是建立在存活对象少、垃圾对象多的前提下的,这种情况在新生代经常发生,老年代很难出现这种情况。


标记一清除算法的确可以应用在老年代中,但是该算法不仅执行效率低下,而且在执行完内存回收后还会产生内存碎片,所以JVM的设计者认为前两种都有问题,即提出了第三种垃圾收集算法:标记-整理算法,可以说是整合了前两种的优势。


前面标记部分同标记清除部分,不同的地方在于,标记清除中只是把可回收的对象进行垃圾回收,不会对剩余的内存空间进行整理,而标记整理则会对存活的对象进行整理,截图对比如下所示:


微信截图_20220523212528.png


3.2、标记-清除与标记整理算法区别


标记-压缩算法的最终效果等同于标记-清除算法执行完成后,再进行一次内存碎片整理,因此,也可以把它称为标记-清除-压缩(Mark-Sweep-Compact)算法。


二者的本质差异在于标记-清除算法是一种非移动式的回收算法,标记-压缩是移动式的。是否移动回收后的存活对象是一项优缺点并存的风险决策。可以看到,标记的存活对象将会被整理,按照内存地址依次排列,而未被标记的内存会被清理掉。如此一来,当我们需要给新对象分配内存时,JVM只需要持有一个内存的起始地址即可,这比维护一个空闲列表显然少了许多开销。


3.3、优缺点


优点: 则是一定程度上解决了前两种算法的缺陷,1)消除了标记-清除算法当中,内存区域分散的缺点;2)不用像复制算法一样,内存减半的高额代价。


缺点:


1)从效率上讲,是不如复制算法的。


2)移动对象的同时,如果对象被其他对象引用,则还需要调整引用的地址


3)移动过程中,需要全程暂停用户应用程序。


3.4、小结


标记清除 标记整理 复制
速率 中等 最慢 最快
空间开销 少(但会堆积碎片) 少(不堆积碎片) 通常需要活对象的2倍空间(不堆积碎片)
移动对象


结论:没有最好的算法,只有最合适的算法。(不然那还有这么多算法的存在勒)

堆部分,年轻代是采用复制算法进行垃圾回收,因为年轻代一般都是存活时间不长的对象,在第一次进行垃圾回收的时候,会把大部分的对象清除掉,这种情况下使用复制算法,只需要把少量存活的对象放入到另一块闲置的内存块中即可。


而老年代中,一般对象的存活比例会很高,这种情况下,使用复制算法不能很好的提高性能和效率,把存活的对象移到另一个内存块时,会由于对象存活多而消耗的时间多,从而影响效率,这种情况下,使用标记整理或者标记清除比较合适。


四、自言自语


每天的生活,慢慢变的充实,未来很长,我们一起努力!!!


目录
相关文章
|
4月前
|
Arthas 存储 算法
深入理解JVM,包含字节码文件,内存结构,垃圾回收,类的声明周期,类加载器
JVM全称是Java Virtual Machine-Java虚拟机JVM作用:本质上是一个运行在计算机上的程序,职责是运行Java字节码文件,编译为机器码交由计算机运行类的生命周期概述:类的生命周期描述了一个类加载,使用,卸载的整个过类的生命周期阶段:类的声明周期主要分为五个阶段:加载->连接->初始化->使用->卸载,其中连接中分为三个小阶段验证->准备->解析类加载器的定义:JVM提供类加载器给Java程序去获取类和接口字节码数据类加载器的作用:类加载器接受字节码文件。
427 55
|
9月前
|
监控 算法 Java
Java虚拟机(JVM)垃圾回收机制深度剖析与优化策略####
本文作为一篇技术性文章,深入探讨了Java虚拟机(JVM)中垃圾回收的工作原理,详细分析了标记-清除、复制算法、标记-压缩及分代收集等主流垃圾回收算法的特点和适用场景。通过实际案例,展示了不同GC(Garbage Collector)算法在应用中的表现差异,并针对大型应用提出了一系列优化策略,包括选择合适的GC算法、调整堆内存大小、并行与并发GC调优等,旨在帮助开发者更好地理解和优化Java应用的性能。 ####
225 27
|
10月前
|
监控 算法 Java
Java虚拟机(JVM)的垃圾回收机制深度解析####
本文深入探讨了Java虚拟机(JVM)的垃圾回收机制,旨在揭示其背后的工作原理与优化策略。我们将从垃圾回收的基本概念入手,逐步剖析标记-清除、复制算法、标记-整理等主流垃圾回收算法的原理与实现细节。通过对比不同算法的优缺点及适用场景,为开发者提供优化Java应用性能与内存管理的实践指南。 ####
|
4月前
|
缓存 算法 Java
JVM深入原理(八)(一):垃圾回收
弱引用-作用:JVM中使用WeakReference对象来实现软引用,一般在ThreadLocal中,当进行垃圾回收时,被弱引用对象引用的对象就直接被回收.软引用-作用:JVM中使用SoftReference对象来实现软引用,一般在缓存中使用,当程序内存不足时,被引用的对象就会被回收.强引用-作用:可达性算法描述的根对象引用普通对象的引用,指的就是强引用,只要有这层关系存在,被引用的对象就会不被垃圾回收。引用计数法-缺点:如果两个对象循环引用,而又没有其他的对象来引用它们,这样就造成垃圾堆积。
133 0
|
4月前
|
算法 Java 对象存储
JVM深入原理(八)(二):垃圾回收
Java垃圾回收过程会通过单独的GC线程来完成,但是不管使用哪一种GC算法,都会有部分阶段需要停止所有的用户线程。这个过程被称之为StopTheWorld简称STW,如果STW时间过长则会影响用户的使用。一般来说,堆内存越大,最大STW就越长,想减少最大STW,就会减少吞吐量,不同的GC算法适用于不同的场景。分代回收算法将整个堆中的区域划分为新生代和老年代。--超过新生代大小的大对象会直接晋升到老年代。
96 0
|
6月前
|
缓存 监控 算法
JVM简介—2.垃圾回收器和内存分配策略
本文介绍了Java垃圾回收机制的多个方面,包括垃圾回收概述、对象存活判断、引用类型介绍、垃圾收集算法、垃圾收集器设计、具体垃圾回收器详情、Stop The World现象、内存分配与回收策略、新生代配置演示、内存泄漏和溢出问题以及JDK提供的相关工具。
JVM简介—2.垃圾回收器和内存分配策略
|
6月前
|
监控 算法 Java
JVM—垃圾收集算法和HotSpot算法实现细节
JVM的垃圾收集算法和HotSpot的实现细节复杂但至关重要,通过理解和掌握这些算法,可以为Java应用程序选择合适的垃圾收集器,并进行有效的性能调优。选择适当的垃圾收集策略,结合合理的内存配置和日志分析,能够显著提升应用的运行效率和稳定性。
103 15
|
10月前
|
机器学习/深度学习 监控 算法
Java虚拟机(JVM)的垃圾回收机制深度剖析####
本文深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法、性能调优策略及未来趋势。通过实例解析,为开发者提供优化Java应用性能的思路与方法。 ####
223 28
|
9月前
|
算法 网络协议 Java
【JVM】——GC垃圾回收机制(图解通俗易懂)
GC垃圾回收,标识出垃圾(计数机制、可达性分析)内存释放机制(标记清除、复制算法、标记整理、分代回收)
|
9月前
|
存储 监控 算法
Java虚拟机(JVM)垃圾回收机制深度解析与优化策略####
本文旨在深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法及参数调优方法。通过剖析垃圾回收的生命周期、内存区域划分以及GC日志分析,为开发者提供一套实用的JVM垃圾回收优化指南,助力提升Java应用的性能与稳定性。 ####

热门文章

最新文章