垃圾清除阶段之标记 - 清除算法 复制算法 标记 - 压缩算法及算法的对比 【图文】

清除阶段(Sweep)

一个对象出现第一次没有被引用的情况,就会被加入到F-Queue队列等待执行finalize()方法判断是否有机会复活或者直接被当作垃圾回收。以便有足够的可用内存空间为新对象分配空间。

目前JVM有三种常见的垃圾回收算法:标记 - 清除算法(Mark - Sweep)复制算法标记压缩算法

一、标记 - 清除算法(Mark - Sweep)

1、背景:标记 - 清除算法(Mark - Sweep)是一种非常基础和常见的垃圾回收算法,该算法被J.MaCarthy等人再1960年提出并应用于Lisp语言。

2、原理:当堆中有效内存空间被耗尽的时候,就会停止整个程序(也被称之为stop the world 所谓的STW),然后进行两项工作,第一项则是标记。第二项则是清除。

(1)标记:Collector从引用根节点开始遍历,标记所有被引用的对象。一般是在对象的Header中记录为可达对象。

(2)清除:Collector对堆内存从头到尾进行线性的遍历,如果发现某个对象在其Header中没有标记为可达对象,则将其回收。 图文:
垃圾清除阶段之标记 - 清除算法 复制算法 标记 - 压缩算法及算法的对比 【图文】_第1张图片
3、缺点:
➢效率不算高( 多次O(n)遍历 );
➢在进行GC的时候,需要停止整个应用程序,导致用户体验差;
➢这种方式清理出来的空闲内存是不连续的,产生内存碎片。需要维护一个空闲列表

4、注意:何为清除?
这里所谓的清除并不是真的置空,而是把需要清除的对象地址保存在空闲的地址列表里。下次有新对象需要加载时,判断垃圾的位置空间是否够,如果够,就存放。是一种对原有的“垃圾”空间数据覆盖。

二、复制算法(Copying)

1、原理:将活着的内存空间分为两块,每次只使用其中一块,在垃圾回收时将正在使用的内存中的存活对象复制到未被使用的内存块中,之后清除正在使用的内存块中的所有对象,交换两个内存的角色,最后完成垃圾回收
垃圾清除阶段之标记 - 清除算法 复制算法 标记 - 压缩算法及算法的对比 【图文】_第2张图片
2、在堆中的幸存者0区和幸存者1区,也是采用这种复制算法。

3、由于空闲的内存是规整的,所以创建对象时分配内存,采用的时是指针碰撞。

4、优点:
(1)没有标记和清除过程,实现简单,运行高效(是建立在每次存活的对象都不是很多的情况)
(2)复制过去以后保证空间的连续性,不会出现“碎片”问题。


5、缺点:
(1)此算法的缺点也是很明显的,就是需要两倍的内存空间。
(2)对于G1这种分拆成为大量region的GC,复制而不是移动,意味着GC需要维护region之间对象引用关系,不管是内存占用或者时间开销也不小,毕竟是要把全部存活的对象都复制一遍,对象的地址也要跟着变化,引用它的对象的引用地址也要做相应的地址调整。。


6、特别的:
如果系统中的垃圾对象很多,复制算法就不会很理想,因为复制算法需要复制的存活对象数量并不会太大,或者说非常低才行,而堆中幸存者0 、1区的对象就满足这样的特点,一次回收就不会去复制太多的对象,那么效率也就很高了。

三、标记 - 压缩算法(Mark - Compact)

叫做标记 - 压缩算法或者标记 - 整理算法

1、背景:
复制算法的高效性是建立在存活对象少、垃圾对象多的前提下的。这种情况在新生代经常发生,但是在老年代,更常见的情况是大部分对象都是存活对象。如果依然使用复制算法,由于存活对象较多,复制的成本也将很高。因此,基于老年代垃圾回收的特性,需要使用其他的算法。

标记一清除算法的确可以应用在老年代中,但是该算法不仅执行效率低下,而且在执行完内存回收后还会产生内存碎片,所以JVM的设计者需要在此基础之上进行改进。标记 - 压缩(Mark - Compact) 算法由此诞生。

2、原理:
第一阶段和标记 - 清除算法的标记过程一样,从根节点开始标记所有被引用对象

第二阶段将所有的存活对象压缩到内存的一端,按顺序排放。之后,清理边界外所有的空间

垃圾清除阶段之标记 - 清除算法 复制算法 标记 - 压缩算法及算法的对比 【图文】_第3张图片

3、优点:
(1)消除了标记-清除算法当中,内存区域分散的缺点,我们需要给新对象分配内存时,JVM只需要持有一个内存的起始地址即可。
(2)消除了复制算法当中,内存减半的高额代价。


4、缺点:
(1)从效率上来说,标记-整理算法要低于复制算法。
(2)移动对象的同时,如果对象被其他对象引用,则还需要调整引用的地址。
(3)移动过程中,需要全程暂停用户应用程序。即: STW

不同指标上对比三种算法


1、三种垃圾回收算法标记 - 清除、复制算法、标记压缩(整理)算法 的比较:

Mark-Sweep Mark-Compact Copying
速度快慢 中等 最慢 最快
空间开销 少(会堆积碎片) 少(不堆积碎片) 通常需要活对象的2倍大小(不堆积碎片)
移动对象

2、效率上来说,复制算法是当之无愧的老大,但是却浪费了太多内存(有点像空间换时间的做法)。
而为了尽量兼顾上面提到的三个指标,标记-整理算法相对来说更平滑一些,但是效率上不尽如人意,它比复制算法多了一个标记的阶段,比标记-清除多了一个整理内存的阶段。

一篇看完可以面试的 JVM垃圾回收(Garbage Collection篇)分享 【图文并茂】推荐

本文部分内容来自尚硅谷,外加自行整理记录

有用点个关注,手留余香!

你可能感兴趣的:(Java虚拟机,标记-清除算法,复制算法,标记,-,压缩算法)