教育行业A股IPO第一股(股票代码 003032)

全国咨询/投诉热线:400-618-4000

JVM的三种垃圾回收算法【Java高级】

更新时间:2022年06月15日14时30分 来源:传智教育 浏览次数:

1.标记清除法

标记清除法

解释:

1.找到GCRoot对象,即那些一定不会被回收的对象,如正执行方法内局部变量引用的对象、静态变量引用的对象

2.标记阶段:沿看GC Root对象的引用链找,直接或间接引用到的对象加上标记

3.清除阶段:释放未加标记的对象占用的内存

要点:

·标记速度与存活对象线性关系

·清除速度与内存大小线性关系

·缺点是会产生内存碎片

2.标记整理法

JVM垃圾回收算法标记清除法

需要先找到 GC Root 对象,即那些一定不会被回收的对象,如正执行方法内局部变量引用的对象、静态变量引用的对象。

标记阶段:沿着 GC Root 对象的引用链找,直接或间接引用到的对象加上标记。

清除阶段:释放未加标记的对象占用的内存。

3.GC 与分代回收算法

GC 的目的在于实现无用对象内存自动释放,减少内存碎片、加快分配速度。

GC 要点:

回收区域是堆内存,不包括虚拟机栈,判断无用对象,使用可达性分析算法,三色标记法标记存活对象,回收未标记对象。GC具体的实现称为垃圾回收器,GC大都采用了分代回收思想。

理论依据是大部分对象朝生夕灭,用完立刻就可以回收,另有少部分对象会长时间存活,每次很难回收根据这两类对象的特性将回收区域分为新生代和老年代,新生代采用标记复制法、老年代一般采用标记整理法

根据 GC 的规模可以分成 Minor GC,Mixed GC,Full GC

(1)分代回收

伊甸园 eden,最初对象都分配到这里,与幸存区 survivor(分成 from 和 to)合称新生代,

代分回收法

当伊甸园的内存不足,标记伊甸园与from(现阶段没有)的存活对象。

将存活对象采用复制算法复制到to中,复制完毕后,伊甸园和from内存都得到释放。

将from和to交换位置
交换位置
经过一段时间后伊甸园的内存又出现不足
标记伊甸园与from(现阶段没有)的存活对象

将存活对象采用复制算法复制到to中


复制完毕后,伊甸园和from内存都得到释放

将 from和 to交换位置

老年代old,当幸存区对象熬过几次回收(最多15次),晋升到老年代(幸存区内存不足或大对象会导致提前晋升)

GC规换

·Minor GC发生在新生代的垃圾回收,暂停时间短

·Mixed GC新生代+老年代部分区域的垃圾回收,G1收集器特有

·Full GC新生代+老年代完整垃圾回收,暂停时间长,应尽力避免

三色标记

即用三种颜色记录对象的标记状态:黑色-已标记,灰色-标记中,白色-还未标记,起始的三个对象还未处理完成,用灰色表示。

三色标记

该对象的引用已经处理完成,用黑色表示,黑色引用的对象变为灰色

依次类推


沿着引用链都标记了一遍


最后为标记的白色对象,即为垃圾

jvw垃圾标注

并发漏标问题

比较先进的垃圾回收器都支持并发标记,即在标记过程中,用户线程仍然能工作。但这祥带来一个新的问题,如果用户线程修改了对象引用,那么就存在漏标问题。例如:

如图所示标记工作尚未完成

用户线程同时在工作,断开了第一层3、4两个对象之间的引用,这时对于正在处理3号对象的垃圾回收线程来讲,它会将4号对象当做是白色垃圾。

但如果其他用户线程又建立了2、4两个对象的引用,这时因为2号对象是黑色已处理对象了,因此垃圾回收线程不会察觉到这个引用关系的变化,从而产生了漏标。

如果用户线程让黑色对象引用了一个新增对象,一样会存在漏标问题。

漏标

因此对于并发标记而言,必须解决漏标问题,也就是要记录标记过程中的变化。有两种解决方法:

Incremental Update 增量更新法,CMS垃圾回收器采用。思路是拦截每次赋值动作,只要赋值发生,被赋值的对象就会被记录下来,在重新标记阶段再确认一遍

 Snapshot At The Beginning,SATB原始快照法,G1垃圾回收器采用思路也是拦截每次赋值动作,不过记录的对象不同,也需要在重新标记阶段对这些对象二次处理,新加对象会被记录,被删除引用关系的对象也被记录

垃圾回收器-Parallel Gc

·eden内存不足发生Minor GC,采用标记复制算法,需要暂停用户线程

·old内存不足发生Full GC,采用标记整理算法,需要暂停用户线程

·注重吞吐量

垃圾回收器·ConcurrentMarkSweep Gc

·它是工作在old老年代,支持并发标记的一款回收器,采用并发清除算法

。并发标记时不需暂停用户线程

。重新标记时仍需暂停用户线程

·如果并发失败(即回收速度赶不上创建新对象速度),会触发FullGC

·注重响应时间

垃圾回收器-G1GC

·响应时间与吞吐量兼顾

·划分成多个区域,每个区域都可以充当eden,survivor,old,humongous,其中humongous专为大对象准备

·分成三个阶段:新生代回收、并发标记、混合收集

·如果并发失败(即回收速度赶不上创建新对象速度),会触发FulGC

G1回收阶段·新生代回收

1.初始时,所有区域都处于空闲状态

G1回收阶段

创建了一些对象,挑出一些空闲区域作为伊甸园区存储这些对象

储存对象

当伊甸园需要垃圾回收时,挑出一个空闲区域作为幸存区,用复制算法复制存活对象,需要暂停用户线程。

幸存区

复制完成,将之前的伊甸园内存释放。

释放内存

随着时间流逝,伊甸园的内存又有不足

将伊甸园以及之前幸存区中的存活对象,采用复制算法,复制到新的幸存区,其中较老对象晋升至老年代。


释放伊甸园以及之前幸存区的内存。

放在幸存区内存

G1回收阶段·并发标记与混合收集

1.当老年代占用内存超过阈值后,触发并发标记,这时无需暂停用户线程。


并发标记之后,会有重新标记阶段解决漏标问题,此时需要暂停用户线程。这些都完成后就知道了老年代有哪些存活对象,随后进入混合收集阶段。此时不会对所有老年代区域进行回收,而是根据暂停时间目标优先回收价值高(存活对象少)的区域(这也是Gabage First名称的由来)。

回收

混合收集阶段中,参与复制的有eden、survivor、old,下图显示了伊甸园和幸存区的存活对象复制。

存活对象复制

下图显示了老年代和幸存区晋升的存活对象的复制。

老年代和幸存区晋升

复制完成,内存得到释放。进入下一轮的新生代回收、并发标记、混合收集。

0 分享到:
和我们在线交谈!