简介JVM的Serial及ParNew收集器

Serial:
串行收集器,JVM client模式下的默认收集器,使用复制算法,在进行垃圾回收时会暂停其他所有的工作线程(stop the world,简称STW)直至回收结束,因此会影响用户的正常使用体验,但是因为少了多线程切换的开销,相较于其他收集器能够更加专注于垃圾回收,在单核场景下效率极高,并且在回收较小内存(几十或者一两百兆)时,停顿时间是毫秒级的。推荐使用场景:年轻代占用几十兆到一两百兆的桌面应用。
使用方式:-XX:+UseSerialGC,打开该开关后,使用Serial(年轻代)+Serial Old(老年代) 组合进行GC。
【简介JVM的Serial及ParNew收集器】

ParNew:
并行收集器,Serial的多线程版本,使用多条线程进行垃圾回收,其他特性与Serial一致。需要注意的是,ParNew在单核甚至双核环境下绝对不会有比Serial收集器更好的效果,但是随着CPU数量的增加ParNew相较于Serial的优势会越来越明显,但并不是成倍增长的,原因还是那个,多线程切换开销。
另外ParNew用于垃圾回收的线程可用参数-XX:ParallelGCThreads=n进行配置。建议n与主机逻辑cpu数一致。
使用方式:-XX:+UseParNewGC,打开该开关后,使用ParNew(年轻代)+Serial Old(老年代)组合进行GC。另外,ParNew是CMS收集器的默认年轻代收集器。


简单比较下两款收集器的使用效果,测试结果直接写在注释:

/** * 测试比较Serial及ParNew两个收集器 * -Xms2048m -Xmx2048m -XX:+PrintGCDetails -XX:+PrintFlagsFinal * * -XX:+UseSerialGC * gctime:100次,耗时107.640ms * * -XX:+UseParNewGC * 测试机逻辑cpu个数为4 * ParallelGCThreads=4 * gctime:100次,耗时59.583ms * ParallelGCThreads=3 * gctime:100次,耗时77.294ms * ParallelGCThreads=1 * gctime:100次,耗时137.109ms * ParallelGCThreads=5(可以超过主机逻辑cpu个数,但好像并没有意义) * gctime:100次,耗时76.557ms * * 测试结论:逻辑cpu的个数越多,ParNew相比Serial收集器的优势会越明显,但并不是成倍增长的,因为线程之间的频繁切换会消耗一定时间,因此,单核cpu,甚至双核cpu下Serial是要优于ParNew的 * 另外,ParallelGCThreads配成与主机逻辑cpu个数一致,效果是最好的。 * @author ljl */ public class TestSerialVSParNew { private static int _10MB = 10 * 1024 * 1024; public static void main(String[] args) throws InterruptedException { for (int i = 0; i < 500; i++) { //不断往Eden区分配对象,触发minorGC byte[] memory = new byte[10 * _10MB]; Thread.sleep(100); } } }







    推荐阅读