上一篇文章介绍了,java虚拟机怎么判断一个对象是否可以回收。本文介绍一下垃圾收集算法。
1.标记-清除 算法
顾名思义,“标记-清除”算法分为“标记”和“清除”两个阶段。首先标记出所需要回收的对象,然后统计清除这些标记的对象。
标记以后的内存区域:
活动 | 活动 | ||
活动 | 活动 | ||
活动 |
清除以后的内存区域:
活动 | 活动 | ||
活动 | 活动 | ||
活动 |
1).标记-清除算法的不足
(1).效率不高,标记和清楚两个过程的效率都不高。
(2).空间问题,标记-清除算法会造成大量的碎片空间,导致以后分配大对象时,因无法找到足够大的空间而提前触发垃圾回收操作。
2.复制算法
复制算法是将内存按容量划分为大小相等的两块区域,每次只使用其中的一块,当这一块使用完之后,将活着的对象复制到一块区域,然后将过时的另一半空间全部清理。
复制算法只针对半个区域进行内存回收,不存在内存碎片化的情况,运行高效。代价是将可使用内存缩小为原来的一般。代价有点高哈。
复制算法主要针对对象死亡率高的区域,比如新生代。对象存活率高时,就需要进行较多的复制操作(使用空间总是被填满),效率将会变低。老年代一般不能直接使用复制算法。
3.标记-整理 算法
标记-整理算法在标记以后,不会直接进行清除,而是让存活的对象都向一端移动,然后直接清理掉边界以外的内存。
整理前内存空间:
活动 | 已标记 | 活动 | 活动 |
活动 | 活动 | 已标记 | 已标记 |
活动 | 已标记 | 活动 | 已标记 |
整理后内存空间:
活动 | 活动 | 活动 | 活动 |
活动 | 活动 | 活动 | |
老年代一般使用标记整理算法。