垃圾收集器
新生代收集器:
一、Serial(串行收集器)
工作方式:这是一个单线程收集器,在进行垃圾收集时,必须暂停其他所有的工作线程,直到垃圾收集完成。(Stop The World)
优点:简单而高效,单线程对于单核CPU来说,由于没有切换线程的开销,所以性能高。
缺点:单线程收集,且必须暂停其他所有的工作线程。
适用在Client模式下的新生代垃圾收集。
二、ParNew(Parallel New , Serial的多线程版本)
工作方式:Serial的多线程版本,其余参考Serial收集器。
从上图可知,只有ParNew可以与CMS进行搭配使用。Server模式下的首选新生代收集器。
三、Parallel Scavenge (吞吐量优先收集器)
工作方式:多线程的垃圾收集器。目标是达到一个可控制的吞吐量(Throughput)。吞吐量 = 运行用户代码时间 / (运行用户代码时间+垃圾收集时间)。例如:虚拟机总共运行了100分钟,垃圾收集用时1分钟,则吞吐量为 99/100 = 99%
优点:吞吐量大,则适用于后台运行多的任务。
缺点:停顿时间短,适合做交互的任务。而高吞吐量,则表明该收集器努力做任务,而忽略了停顿的时间,所以不适合做交互型的任务。
老年代收集器:
四、CMS(Concurrent Mark Sweep,并发标记清除)
CMS收集器是一种以获取最短回收停顿时间为目标的收集器。特别适合web项目,在与用户交互过程中,GC停顿时间短。
并发标记,并发清除两个阶段,可以与用户线程一起并发执行。
工作原理:
1、初始标记:需要Stop The World,标记GC Roots能直接关联到的对象,内容少,速度快。
2、并发标记:标记GC Roots关联的引用链的对象,内容多,速度慢。
3、重新标记:需要Stop The World,修正并发标记期间因用户程序继续运行而导致的标记产生变动的那一部分对象的标记记录。
4、并发清除:
优点:由于可以并发执行,所以GC停顿时间短。
缺点:
1、CMS默认启动的回收线程数是 (CPU数量+3)/ 4 ,在并发回收时,会占用当前用户线程一直到GC结束,所以会导致吞吐量下降。
2、CMS收集器无法处理浮动垃圾。由于标记是并发执行的,也就是说标记的时候,用户线程也会产生新的无用对象,这些对象称为“浮动垃圾”。
3、根据名字可知,CMS并发标记清除,清除过后,会产生大量的碎片空间。当分配大对象时,可能会提前触发GC。(可以设置是否进行压缩处理,设置为压缩处理后,就没有碎片空间问题,但是因为压缩期间无法并发处理,所以会导致性能下降。)
五、Serial Old (MSC)
工作方式:用标记-整理算法实现的单线程老年代垃圾收集器。
适用于Client模式下的垃圾收集。
六、Parallel Old
工作模式:Parallel Scavenge的老年代版本。
跟Parallel Scavenge进行搭配使用,适用于“吞吐量优先”的工作场合。例如大量的运行任务。
七、G1(Garbage-First)
面向服务端应用的垃圾收集器。
工作方式:
1、内存的划分:新生代和年老代,不再物理隔离。G1将整个Java堆划分为多个大小相等的独立区域(Region),新生代和老年代均由多个Region组成。
2、收集方式:G1跟踪各个Region里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需的时间等经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region(这就是Garbage-First名称的由来)。
3、如何解决各个Region直接的对象引用?
每个Region中维护一个Remembered Set,在被另外的Region引用时,将在被引用的Region中的Remembered Set中记录相应的信息。当进行标记时,就可以根据Remembered Set的内容扫描指定的Region,避免对整个堆进行扫描。
优点:
1、并发与并行:充分利用多CPU,缩短Stop The World的停顿时间。
2、分代收集:新生代,年老代,永久代
3、空间整合:年轻代基于复制算法来实现的收集器,年老代基于标记-整理算法实现的收集器。
4、可预测的停顿:可以指定GC耗时(并不是指定的耗时越短,速度越快。因为耗时是根据收集的内存大小来定的,如果指定的时间短,则JVM分配的堆空间就变小了,以符合设置的GC消耗时间。或者以牺牲次数的方式,进行GC。比如原本需要1次GC,耗时100ms。但是现在变为2次GC,每次耗时60ms。)
总结:
新生代使用复制算法进行垃圾收集,老年代使用标记-整理算法进行垃圾收集。
番外篇:
JVM的Client,Service模式的解析:
1、Client模式下,类似于C/S架构中的C,启动速度快,运行速度慢。
2、Service模式下,类似于C/S架构中的S,启动速度慢,运行速度快。
默认情况下,虚拟机会根据电脑的配置,选择相应的模式进行启动。例如服务器一般都是CPU核数多,内存大的机器,如果JVM甄别到符合服务器的标准,则启动服务器模式。
并行,并发:需要添加多核的概念
1、并行:多条垃圾收集线程并行工作,但是用户线程仍然处于等待状态。
2、并发:多线程,线程间切换,交替进行。用户线程与垃圾线程同时执行。可以并行,也可以交替进行。