JVM(二) 常见的垃圾回收算法

时间:2023-02-16 22:40:30

看完本文你会了解什么:

1.了解常见回收算法

垃圾回收算法是JVM在整理内存时候的策略。上一篇我们介绍了JVM的基本结构,那么JVM的Java堆中又是如何处理那些没用的垃圾内存的呢?下面将介绍几种常见的垃圾回收算法

引用计数法

引用计数法基本上最简单的垃圾回收策略,它的核心思想是:
当有指针指向某实例时,计数加一, 当删除一个指针时,计数减一,当计数为0时,说明该实例没有引用可以被垃圾回收器回收。
这种回收策略的缺点是显而易见的:
1.维护引用计数是有开销的
2.计数的保存会消耗额外的空间
3.无法处理循环引用

标记清除

标记清除,顾名思义分为2步:1.标记 2.清除。标记清除会先从根扫描所有的可达对象,不可达的对象就是无用的垃圾对象。然后回收器集中清除垃圾对象。这种策略的缺点是:
1.标记整理的时候需要JVM停止其它工作
2.整理后产生了很多内存碎片

复制算法

复制算法的核心是:将内存空间分为两块,每次只使用其中一块,在垃圾回收时,将正在使用的内存区间中的存活对象复制到另一块,之后,清除正在使用的一块中的所有对象,然后两块区域交换角色。缺点:
1.将内存折半,利用率低

标记压缩算法

标记压缩算法在标记清除算法的基础上做了些改进,它在标记完所有的有效对象后,将有效的内存压缩到一起,然后再清除其它区域。

分代算法

因为每一种算法都有各自的优略,所以根据对象的不同特点使用不同的回收算法能够显著提高垃圾回收的效率。分代算法正是基于这种思想产生的,像上一篇我们介绍的Java堆,一般有年轻代和老年代。年轻代的特点就是对象的存活时间短,所以这个时候选用复制算法是非常合适的。 而老年代中的对象一般不会被回收,这个时候如果也用复制算法显然是不合适的, 这个时候JVM选择了标记压缩算法。
对于年轻代和老年代来说,一般年轻代的垃圾回收频率高耗时短,老年代的回收频率低耗时长。为了应对这种情况,JVM使用了一种卡表的数据结构。其中记录某一区域的老年代对象是否持有年轻代对象的引用,如果没有持有的话就不需要扫描老年代,可以加大年轻代的回收效率。

分区算法

分代算法按照对象的生命周期将对象分为了两部分,而分区算法将整个堆空间划分成不同的区域,每一个区域都独立使用,独立回收。这种算法的好处是可以控制一次回收的区域个数,这样可以根据目标的停顿时间选择合适的回收个数,从而达到减少GC停顿的目的。

JVM(二) 常见的垃圾回收算法