概念
垃圾收集是很多使用JAVA语言的IT从业者了解得比较少的地方。
但是涉及性能时非常重要。大公司面试除了算法,这部分也是会经常考察的地方。
《深入理解JAVA虚拟机》一书中讲到JVM的垃圾收集算法和垃圾收集器。
垃圾收集算法分为:
1、标记清除算法
通常用在回收老年代内存。
最早的搜集算法就是标记清除(Mark-Sweep)算法了。
其原理是分为标记和清除两个阶段:
首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。
主要不足两个:
一个是效率问题,标记过程和清除过程效率不高。
二是容易产生内存碎片,需要分配较大对象时,只能再触发一次垃圾回收动作。
2、复制算法
通常用在回收新生代内存。
复制算法是目前也比较常用的算法。
它的原理是:
将可用内存花费大小相等的三块,两块是Survivor(幸存者分区),另外一块是Eden(伊甸园分区)
每次只使用Eden和一个Survivor1分区,回收时,将当前Eden和Survivor中还活着的对象一次性的复制到另外一块Survivor2空间上,如果内存不够就向老年代内存区域借用内存空间进行分配。
也就说,如果Survivor2中内存不够时,这些要回收的对象就会变成老年代内存,意味着这部分将使用老年代垃圾回收机制进行回收。
3、标记整理算法
通常用在回收老年代内存。
它和标记清理算法的差不多,主要区别是标记后,然后把对象进行排列整理,保留的放前面,要回收的放后面,然后回收后面那一堆垃圾对象。
优点是没有碎片内存空间,内存利用率较高。
4、分代搜集算法
说白了其实就是把对象分为新生代、老年代,永久代(JDK8已经移除了永久代,引入元空间)。每一代使用上面列的一种垃圾回收算法进行清理。
另外,由于老年代的内存对象,垃圾率比较高,基本都是要清理的,所以使用复制算法不太好,占用内存过多,这种情况下,一般使用标记-清除或者标记-整理算法来清理。