JVM——GC(垃圾回收)算法

一.垃圾回收的基本概念

垃圾回收(GC,Garbage Collection),指内存中不会再被使用的对象清理掉。

垃圾回收有很多种算法:如引用计数法、标记压缩法、复制算法、分代/分区的思想

二.垃圾回收算法

1.引用计数法:这是个比较古老而经典的垃圾收集算法,其核心就是在对象被其他所引用时计数器+1,当应用时效时则-1,但是这种方式有非常严重的问题:无法处理循环引用的情况。还有就是每次进行+-操作比较浪费系统的性能

2.标记清除法:就是分为标记和清除两个阶段进行处理内存中的对象。这种方式也有非常大的弊端,就是空间碎片问题。垃圾回收后的空间不是连续的,不连续的内存空间的工作效率要低于连续的内存空间

原理:对于“活”的对象,一定可以追溯到其存活在堆栈、静态存储区之中的引用。这个引用链条可能会穿过数个对象层次。第一阶段:从GC roots开始遍历所有的引用,对有活的对象进行标记。第二阶段:对堆进行遍历,把未标记的对象进行清除。这个解决了循环引用的问题。

3.复制算法:其核心思想就是将内存空间划分为两块,每次只使用其中一块,在垃圾回收时,将正在使用的内存中的存留对象复制到未被使用的内存块中去,之后去清除之前正在使用的内存块中所有的对象,反复去交换两个内存的角色,完成垃圾收集。(java新生代里的s0和s1空间就是使用这种算法)

4.标记压缩法:标记压缩分在标记清除法的基础上做了优化,把存活的对象压缩到内存的一端,然后进行垃圾清理(老年代使用的就是这种算法)

ps:新生代和老年代采用不同GC算法的原因

先说新生代,因为新生代的对象是很不稳定的,被回收的概率达到80%,所以一个对象基本是被回收的,这个时候如果采用标记压缩法,会导致大量的空间被压缩;而采用复制算法,只有少数的对象会在s0/s1区中做转换

再说说老年代,老年代的对象是经过多次GC算法的回收之后留下来的,非常稳定,这时如果采用复制算法,将消耗大量的空间,并且很多是无谓的复制;而采用标记压缩法,因为对象很稳定,所以压缩的对象其实很少

5.分区算法

jvm把内存分成一个个的小片,每个小片里单独进行GC,目的是为了较少GC的停顿时间

该算法是jdk1.7以后提出 来的,应用不广泛

三.GC停顿

垃圾回收器的任务是识别和回收垃圾对象进行内存清理,为了让垃圾回收器可以高效执行,大部分情况下,会要求系统进入一个停顿状态,停顿的目的是终止所有线程,只有这样系统才会没有新的垃圾产生,同时停顿保证了系统状态在某一瞬间的一致性,也有益于更好地标记垃圾对象。

四.垃圾收集器的种类

1.串行垃圾回收器

单线程进行垃圾回收,对于并行能力弱的计算机来说,串行垃圾回收器的专注性和独占性往往有更好的性能提现。

2.并行垃圾回收器

并行回收器在串行的基础上做了改进,可以使用多个线程同时进行垃圾回收,对云计算能力强的计算机而言,可以有效缩短垃圾回收所需要的实际时间

(1)ParNew回收器

ParNew回收器是一个工作在新生代的垃圾收集器,它只是简单地将串行收集器多线程化,回收策略和算法跟串行回收器一样

(2)ParallelGC回收器

新生代ParallelGC回收器,使用了复制算法的收集器,也是多线程独占形式的收集器,但是ParallelGC回收器有个非常重要的特点,它非常关注系统的吞吐量

(3)ParallelOldGC回收器

与ParallelGC相似,但是其工作空间在老年代

3.CMS(Concurrent Mark Sweep)回收器(主流)

并发标记清除,使用的是标记清除法,主要关注系统停顿的时间

CMS并不是独占的回收器,也就是说,CMS在回收的过程中,程序仍然在不停地工作,又有新的垃圾不断产生,所以在使用CMS过程中应该确保应用程序的内存足够可用。CMS不会等到应用程序饱和时采取回收垃圾,而是到达一定的阀值时就开始回收了,默认是68(阀值可以配置),也就是说,当老年代空间使用率打到68的时候,会执行CMS回收。如果内存使用率增长的很快,在CMS执行过程中就已经出现了内存不足的情况,此时CMS回收就会失败,jvm将启动老年代串行回收器进行垃圾回收,这会导致应用程序中断,直到垃圾回收完成后才会正常工作,这个过程GC的停顿时间可能较长。

标记清除法有个问题是碎片问题,CMS有个参数可以设定多少次CMS垃圾回收之后进行一次压缩

4.G1回收器

jdk1.7中提出,从长期目标来看是取代CMS回收器的。G1属于分代垃圾回收器,区分新生代和老年代,依然有eden和from/to区,不要求整个eden区或者新生代/老年代都空间连续,它使用了分区算法

并行性:G1回收期间可以多线程同时工作

并发性:G1拥有与应用程序交替执行的能力,部分工作可以与应用程序同时执行,在整个GC期间不会完全阻塞应用程序

分代GC:G1依然是个分代的收集器,但是它兼顾新生代和老年代一起工作,之前的垃圾收集器他们或在新生代工作,或在老年代工作,因此这是个很大的不同。

空间整理:G1回收的过程中,不会像CMS那样在若干次GC之后需要进行碎片整理。G1采用了有效复制对象的方式,减少空间碎片

可预见性:由于分区的原因,G1可以只选取部分区域进行回收,缩小了回收范围,提升了性能

猜你喜欢

转载自blog.csdn.net/mweibiao/article/details/80388178