一、垃圾回收算法
1、引用计数:
每个对象每增加一个引用,则引用计数器加1,当计数为0时被判定为可回收对象,但对于循环引用无法处理。
2、标记清除:
从根对象开始标记所有可达对象,其余对象清除。但此时清除后的空间会产生大量内存碎片,如:a、b、c三块连续内存中,可能b被清除而a、c中有存活对象,则一些大对象的存储效率会降低。
根对象一般为方法区中的静态变量、常量以及方法栈的栈帧中局部变量、
3、复制算法:
用于年轻代,年轻代分为Eden区和Survivor区,Survivor区则分为from和to两块空间,from与to两块空间保证只有一块空间处于使用中,垃圾回收时,将所有存活对象复制到from或to空间中,例如:from空间未使用,则存活对象复制到from空间,然后清除Eden与to的所有对象,下一次垃圾回收则将存活对象复制到to空间(此时to空间已被清除,未被使用),然后清除Eden与from空间。当from或to空间不足以存放所有存活对象时,无法存储的对象会被复制到老年代。
4、标记压缩:
标记压缩同样从根对象开始标记可达对象,与标记清除不同的是,它会将存活对象移到内存边界,然后回收其余空间,防止产生内存碎片,一般用于老年代。
5、增量算法:
增量算法是使垃圾回收算法与应用线程交替执行的算法,这样可以使垃圾回收与应用并行,防止应用长时间挂起,但线程的交替执行也会降低系统的吞吐量。
6、分代算法:
根据内存回收的特性将内存空间分为不同区域,采用不同的垃圾回收算法以提高回收效率。
二、垃圾回收器分类:
1、按回收线程数:
串行回收器:单线程垃圾回收,适用于单核cpu及并发能力不强的系统
并行回收器:适合多核cpu且并发能力强的系统
2、按工作模式:
并发式:垃圾回收线程与应用线程交替执行,降低系统停顿时间
独占式:垃圾回收时应用挂起直到回收结束,提高系统吞吐量
3、按碎片处理方式:
压缩式:垃圾回收后将存活对象移至内存边界防止内存碎片产生
非压缩式:垃圾回收后不进行碎片处理
4、按工作区间:
年轻代垃圾回收、老年代垃圾回收:分代使用不同垃圾回收器
三、垃圾处理指标
1、吞吐量:应用总耗时/运行耗时(即(运行耗时-GC耗时)/运行耗时)
2、垃圾回收负载:GC耗时/运行耗时
3、停顿时间:应用暂停时间,独占式总暂停时间较短,并发式垃圾回收与应用线程交互,耗时增加,吞吐量减少
4、垃圾回收频率:越低越好,通常可增大堆空间实现,但会导致回收时的应用停顿时间增加
5、反应时间:对象成为垃圾后多久回收
6、堆分配:良好的垃圾回收器需要合理的堆空间分配
四、垃圾回收器简介
1、Serial
串行回收,独占式,采用复制算法,通过-XX:+UseSerialGC参数使用,指定在年轻代和老年代使用,使用该参数时老年代还可以通过-XX:+UseConcMarkSweepGC启动CMS收集器配和使用。
2、ParNew
并行回收,独占式,采用复制算法,通过-XX:+UseParNewGC使用,指定年轻代采用并行回收,即多个垃圾回收线程同时启用,此时老年代默认采用串行回收,也可以通过-XX:+UseConcMarkSweepGC启动CMS收集器与老年代串行回收配合使用。
3、Parallel
并行回收,独占式,采用复制算法,通过-XX:+UseParallelGC使用,此时老年代默认采用串行回收,与Parnew不同的是,此时可以通过-XX:+UseParallelOldGC使老年代使用并行回收,另外Parallel更加关注系统的吞吐量
4、CMS
只在老年代使用,并发式,可降低系统停顿时间,采用标记清除算法,会产生内存碎片,通过参数可指定碎片处理方式。
5、G1
通过-XX:+UseG1GC开启,老年代与年轻代都使用该收集器,该收集器采用独占式复制算法,所以一定程度上它也完成了内存压缩,减少了内存碎片
图中连线的部分为在老年代和年轻代中可配合使用的收集器。