垃圾收集算法
1. 标记-清除算法
同名字一样,有“标记”和“清除”两个阶段。首先标记出所有要回收的对象,在标记完成后进行统一的回收。
没有被标记的对象将会回收清除掉,而被标记的对象将会留下。
有主要两个不足:
一个是效率不高,标记和清除两个过程的效率都不高,在进行GC的时候会停止程序,因为如果不停止程序,如果new了A对象,然后GC,GC的时候B对象引用了A对象,那么GC之后可能A就是null了,所以要停止程序。
另一个是空间问题,标记清除之后会产出大量不连续的碎片内存,空间碎片太多的话,可能后面在程序运行的时候创建大对象时,无法找到连续的内存空间,从而不得不提前触发另一次gc,
2. 复制算法
它将可用内存划分为大小相同的两块,每次只使用其中的一块,当这一块内存用尽了,就将还存活的对象移动到另外一块空间,然后再把已使用过的空间清理掉。不过这种算法的代价就是可用空间是原来的一半,成本有点高。
eden空间的和2块survivor空间,每次都是使用eden和其中的一块survivor空间存放对象,当回收时,将eden空间和survivor空间存活的对象,放到另外一个survivor空间中,以后清理掉eden和用过的survivor空间。
当survivor空间不够用的时候,会像老年代进行分配担保。
3. 标记-整理
根据老年代的特点,提出了标记-整理算法,标记过程和标记-清除算法一样,但是后续的操作不是直接的去清理。而是让被标记的对象都移动到一端,然后直接清理掉边界以外的内存。
4. 分代收集算法
一般是把java堆分成新生代和老年代,根据他们的特点,新生代用复制算法,老年代用标记-整理算法。