JVM Heap在实现中被切分成了不同的generation,比如生命周期短的对象会放在young generation,而生命周期长的对象放在tenured generation中,如下图
当GC只发生在young generation中,回收young generation中的对象,称为Minor GC;当GC发生在tenured generation时则称为Major GC或者Full GC。一般的,Minor GC的发生频率要比Major GC高很多。
负责Young Generation的collector有三种
Serial
最简单的collector,只有一个thread负责GC,并且,在执行GC的时候,会暂停整个程序(所谓的“stop-the-world”),如下图所示
Parallel Scavenge
和Serial相比,它的特点在于使用multi-thread来处理GC,当然,在执行的时候,仍然会“stop-the-world”,好处在于,暂停的时间也许更短,如下图所示
ParNew
它基本上和Parallel Scavenge非常相似,唯一的区别,在于它做了强化能够和CMS一起使用
负责Tenured Generation的collector也有三种:
Serial Old
单线程,采用的是mark-sweep-compact回收方法,相当于单线程,Serial类似;
Parallel Old
同理,多线程的GC collector
CMS
全称“concurrent-mark-sweep”,它是最并发,暂停时间最低的collector,之所以称为concurrent,是因为它在执行GC任务的时候,GC thread是和application thread一起工作的,基本上不需要暂停application thread,如下图所示
组合方案
6种collector介绍完了。不过,在设定JVM参数的时候,很少有人去分别制定young generation和tenured generation的collector,而是提供了几套选择方案:
-XX:+UseSerialGC
相当于”Serial” + “SerialOld”,这个方案直观上就应该是性能最差的,我的实验证明也确实如此;
-XX:+UseParallelGC
相当于” Parallel Scavenge” + “SerialOld”,也就是说,在young generation中是多线程处理,但是在tenured generation中则是单线程;
-XX:+UseParallelOldGC
相当于” Parallel Scavenge” + “ParallelOld”,都是多线程并行处理;
-XX:+UseConcMarkSweepGC
相当于”ParNew” + “CMS” + “Serial Old”,即在young generation中采用ParNew,多线程处理;在tenured generation中使用CMS,以求得到最低的暂停时间,但是,采用CMS有可能出现”Concurrent Mode Failure”,如果出现了,就只能采用”SerialOld”模式了。