问题:请讲下在java中有哪些垃圾回收算法
分析:该问题主要考察对java中垃圾回收的算法以及使用场景
回答要点:
主要从以下几点去考虑,
1、GC回收算法有哪些
2、每种算法的使用场景
3、基于垃圾回收算法有哪些垃圾回收器
在《java面试一日一题:如何判断一个对象是否为垃圾对象》中知道了java中判断一个对象是否存活,是否可被回收使用的是可达性分析算法,找出了可回收的对象,那么有哪些回收算法可以回收这些对象那
复制算法
复制算法就是从一个地方复制到另外一个地方,针对垃圾回收来说,就是把活着的对象复制到另外一块内存区域,然后之前的内存区域中的对象便可以被回收。在同等大小内存前提下,复制算法的内存使用率比较低,因为它会把内存分为两个部分,如下图
复制算法-回收前
复制算法-回收后
标记-清除算法
标记-清除算法,首先是一个标记的过程,也就是标记出哪些对象是垃圾,然后进行清除操作。该算法不需要像复制算法似的,把内存分为两部分,它可以利用整块的内存,在内存利用率上是没有问题的,但是容易产生内存碎片,随着内存的回收,可能在内存中就不存在整块的大内存,在分配需要连续空间的大对象(数组)时就会发生OOM。如下图
标记清除-算法前
标记清除-算法后
从上图可以看到在使用标记-清除算法后,被标记为垃圾的对象被回收了,释放了内存空间,但是内存中存在了一个隔一个的空,也就是内存碎片,这时如果要分配一个连续的大空间,可能有无法找到空间的情况,发生OOM。
另外,使用标记-清除算法,在进行内存分配的时候采用的内存分配算法一定是空闲列表法。
标记-整理/压缩算法
标记-整理/压缩,是在标记清除的基础上加了一个内存整理的过程,是为了消除内存碎片的,如下图
标记-整理前
标记-整理后
从上图可以看出,使用标记整理算法后内存是规整的,解决了标记-清除算法中内存碎片的问题,但是多了一个内存整理的过程。
分代算法
分代算法,其实不能算是一个垃圾回收的算法,可以理解为一种垃圾回收的方案,即把内存分为不同的块也即代,每一块使用不同的垃圾回收算法。现代主流的垃圾回收器都是使用分代的思想,如下图
上图即是分代算法的示意图,把堆区分为新生代和老年代,新生代又分为Eden S0 S1;新生代使用复制算法,老年代使用标记-清除/标记-整理算法。
有不当之处,欢迎指正,谢谢