JVM垃圾回收入门(二)

垃圾收集器

①串行回收器

原理:在串行垃圾回收器运行时是独占的,需要暂停java应用程序中的线程。
特点:①使用单线程进行垃圾回收,并行能力较弱的计算机更适用,CPU和硬件不是特别优越的场合,它的性能可以超过并行回收器和并发回收器

②独占式的垃圾回收

在回收时其他线程暂停,等待回收完成(STW)
注:新生代串行回收器使用复制算法,老年代使用的是标记压缩算法。

新生代ParNew回收器

原理:它只是简单的将串行回收器多线程化。是独占式的垃圾回收器,使用的是复制算法。
特点:①在并发能力强的CPU上它产生的停顿时间要短与串行回收器
注:一般ParNew回收器的线程数最好与CPU的数量相当,避免过多线程数影响性能。

新生代ParallelGC回收器

原理:表面上它和ParNew回收器一样,多线程、独占式、使用复制算法。
特点:①它非常关注系统的吞吐量!
②支持自适应GC调节策略,这种模式下堆中新生代老年代的比例会自动调节以达到堆大小、吞吐量、停顿时间的平衡点。会尽量控制停顿时间在配置的范围内,那么虚拟机可能会使用一个较小的堆,GC会变得更频繁,吞吐量就会降低。因此吞吐量和停顿时间是相互矛盾不可兼得的。用于手动调优比较困难的场合。

老年代ParallelOldGC回收器

和新生代的ParallelGC相同,只不过是作用在老年代的回收器,使用的是标记压缩算法。

CMS回收器

JVM垃圾回收入门(二)
原理:(Concurrent Mark Sweep并发标记清除)使用的是标记清除法。与ParallelGC和ParallelOldGC不同的是,CMS只要关注的是系统停顿时间。常用于与用户交互较多的场景,注重系统响应速度。CMS垃圾回收器标记过程是独占的,清理过程是非独占的
步骤:​​
A. 初始标记:仅仅标记一下根对象能够直接关联到的对象,速度很快,但是会造成STW
B. 并发标记:初始标记后,程序仍然在运行,无法保证标记出所有存活的对象,并发标记就是由当前标记过的对象出发标记所有可到达的对象。(简单说就是标记程序运行时新产生的存活对象)
C. 预清理:除了为正式清理做准备以外,它还会尝试控制一次停顿时间。由于重新标记是独占CPU的,如果在新生代GC后马上重新标记,会造成停顿时间过长,为了避免它,预处理时会根据历史数据预测下一次新生代GC发生的时间,在当前时间和预测时间的中间时刻进行重新标记。
D. 重新标记:是为了修正并发标记期间,java程序继续运行而导致的对象变化,进行独占CPU重新扫描堆中的对象,进行可达性分析标记存活对象。(例如并发标记是C对象没有引用,后来有对象引用它了,重新扫描重新标记C不会被清除)
E. 并发清理:回收所有的垃圾对象(标记回收法)
F. 并发重置:CMS清除内部状态,为下一次回收做好准备。

问题:
A. 设置CMS回收阈值?
起因:CMS不是独占式回收器,在它并发清理时应用程序仍然在工作,又会有新的垃圾产生,但是无法被清理,如果在CMS执行时出现了内存不足的情况,CMS就会执行失败,同时JVM将启动老年代串行回收器进行回收,同时程序将完全中断知道回收完成。
解决:CMS回收器在达到一定阈值时才会开始回收,通过参数来设定阈值,如果内存增长缓慢可以设定一个稍大的阈值,降低CMS的触发频率,减少老年代回收次数。如果内存增长快则应该降低这个阈值,避免频繁触发老年代串行回收器。

B. 内存碎片问题:
CMS使用的是标记回收算法,在回收后容易出现内存碎片,导致有空间但是无法分配较大的对象,也会*再次进行一次垃圾回收以换取一块连续的内存空间。为了解决,CMS提供了几个用于内存压缩整理的参数。

⑥G1(Garbage_First)回收器(简单了解)

G1回收器在JDK1.7中引入的全新回收器。它属于分代垃圾回收器,使用了分区算法,不要求年轻代老年代连续。
特点:①它兼顾了年轻代和老年代的GC,之前的算法都是只作用于一个区域
②空间整理:G1在回收的过程中会进行适当的对象移动,每次回收都会有效的复制对象,减少空间碎片。
③由于分区的原因,缩小了回收的范围,对全局停顿有良好的控制。