1、标记-清除(Mark-Sweep)算法
标记-清除算法分为两个阶段:标记阶段、清除阶段。
在标记阶段,会标记出所有需要回收的对象,标记完成后,统一回收所有被标记的对象。
缺点:
(1)效率问题,标记和清除阶段效率都不高。
(2)空间问题,会产生大量的不连续的内存碎片,不利于分配较大的对象。
2、复制算法
复制算法将内存按容量划分为大小相等的两块,每次只使用其中一块。当前使用的这一半空间快用完的时候,将还存活的对象复制到另一半上面,过期的对象不会复制,直接被清除。这种方法效率比标记清除算法高,并且也不会出现内存碎片。
缺点:
空间利用率低,内存少了一半。
为解决这个问题,HotSpot虚拟机采用了更加合理的划分方式:
将内存分为较大的一块Eden空间,和两块较小的Survivor空间,比例为8:1:1。这种分配方式,只有10%的空间被浪费。
3、标记-整理算法
标记-整理算法一般用于老年代,它也分为两个过程,标记阶段将过期的内存进行标记,接下来的整理阶段,是将存活的内存向一端移动,然后清除端边界以外的内存。
缺点:
效率比较低,整理过程需要复制和移动,比较耗时。
4、分代收集算法
当前商业虚拟机都采用分代收集算法,根据对象存活周期的不同将内存划分为几块。一般是把java堆分为新生代和老年代,这样就可以根据各个年代的特点,采用最合适的收集算法。
新生代:复制算法
老年代:标记-清除/标记-整理。