1. 标记清除算法
Mark-Sweep算法
首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象
最基础的垃圾回收算法
缺点
- 效率不高
- 产生大量不连续的内存碎片
2.复制算法
Copying算法
为了解决效率问题出现
把内存区域分成两块,只使用一块,满了之后把使用中的内存块中还存活的对象复制到另一块空白区去,然后把整块清除掉
缺点
代价太高,牺牲了一半的可用内存空间
改进
新生代中大多数对象很快就会死,不需要1:1的划分内存空间,而是把内存分成一块比较大的eden空间和两块小的survivor空间,每次使用eden和其中一块survivor
回收的时候,把eden和在使用的survivor中还存活的对象复制到另一块survivor上,然后整块清除
所有商业虚拟机都采用这种算法来回收新生代对象
HotSpot默认内存分配是8:1:1
也就是说同时只有10%的内存空间会被浪费掉
但是当我们一次GC时剩余的存活对象占据内存大于可用内存的10%,多余的对象就要去老年代中分配了
3.标记整理算法
Mark-Compact算法
复制算法在对象存活率较高时操作,效率太低,并且如果不想浪费50%的空间,就要有额外的空间进行分配担保,以应对被使用的内存中所有对象都存活的极端情况,所以在老年代一般不能直接使用这种算法
根据这一情况,有一种新的算法,标记整理
标记与之前的算法一致,但后续不是直接对可回收对象进行清理,而是把所有存活的对象向一端移动,然后直接清除掉另一端到边界的内存
4.分代收集算法
所有商业虚拟机的GC都采用分代收集算法,把java堆分成新生代和老生代,根据各个年代的特点采用最适当的算法