java面试一日一题:java中垃圾回收算法有哪些

问题:请讲下在java中有哪些垃圾回收算法

分析:该问题主要考察对java中垃圾回收的算法以及使用场景

回答要点:

主要从以下几点去考虑,

1、GC回收算法有哪些

2、每种算法的使用场景

3、基于垃圾回收算法有哪些垃圾回收器

 

在《java面试一日一题:如何判断一个对象是否为垃圾对象》中知道了java中判断一个对象是否存活,是否可被回收使用的是可达性分析算法,找出了可回收的对象,那么有哪些回收算法可以回收这些对象那

复制算法

复制算法就是从一个地方复制到另外一个地方,针对垃圾回收来说,就是把活着的对象复制到另外一块内存区域,然后之前的内存区域中的对象便可以被回收。在同等大小内存前提下,复制算法的内存使用率比较低,因为它会把内存分为两个部分,如下图

复制算法-回收前

复制算法-回收后

 

标记-清除算法

标记-清除算法,首先是一个标记的过程,也就是标记出哪些对象是垃圾,然后进行清除操作。该算法不需要像复制算法似的,把内存分为两部分,它可以利用整块的内存,在内存利用率上是没有问题的,但是容易产生内存碎片,随着内存的回收,可能在内存中就不存在整块的大内存,在分配需要连续空间的大对象(数组)时就会发生OOM。如下图

标记清除-算法前

标记清除-算法后

从上图可以看到在使用标记-清除算法后,被标记为垃圾的对象被回收了,释放了内存空间,但是内存中存在了一个隔一个的空,也就是内存碎片,这时如果要分配一个连续的大空间,可能有无法找到空间的情况,发生OOM。

另外,使用标记-清除算法,在进行内存分配的时候采用的内存分配算法一定是空闲列表法。

标记-整理/压缩算法

标记-整理/压缩,是在标记清除的基础上加了一个内存整理的过程,是为了消除内存碎片的,如下图

标记-整理前

标记-整理后

从上图可以看出,使用标记整理算法后内存是规整的,解决了标记-清除算法中内存碎片的问题,但是多了一个内存整理的过程。

分代算法

分代算法,其实不能算是一个垃圾回收的算法,可以理解为一种垃圾回收的方案,即把内存分为不同的块也即代,每一块使用不同的垃圾回收算法。现代主流的垃圾回收器都是使用分代的思想,如下图

上图即是分代算法的示意图,把堆区分为新生代和老年代,新生代又分为Eden S0 S1;新生代使用复制算法,老年代使用标记-清除/标记-整理算法。

 

有不当之处,欢迎指正,谢谢

posted @ 2021-05-14 17:01  良工说技术  阅读(610)  评论(0编辑  收藏  举报