表1 java垃圾收集器选项设置的效果

    java垃圾收集器选项设置 jvm使用的垃圾收集器
    -XX:+UseSerialGC Serial(年轻代), Serial Old(老年代)
    -XX:+UseParallelGC Parallel Scavenge(年轻代), Parallel Old(老年代)
    -XX:+UseConcMarkSweepGC ParNew(年轻代), CMS(老年代)
    -XX:+UseG1GC G1

    表2 不同垃圾收集器设置的GC暂停时间对比

    堆容量(MB) -XX:+UseSerialGC -XX:+UseParallelGC -XX:+UseConcMarkSeeepGC -XX:+UseG1GC
    1024 minor: 130 minor: 45-187 minor: 50-100 10-25
    512 minor: 85-140 minor: 25-40 minor: 30-85 5-45
    256 minor: 35-55
    major:160
    minor: 10-20
    major: 70-120
    minor: 15-50
    cms: 5
    5-10
    128 minor: 15-25
    major: 5-60
    minor: 10
    major: 10-50
    minor: 10-20
    cms: 5
    full: 50-60
    2-10
    full: 10-50

    说明:

    • 表中数据来源于运行 GCLogAnalysis 类产生的GC日志,日志文件在“运行GCLogAnalysis的GC日志”目录下
    • -Xms 和 -Xmx 参数都等于堆容量。
    • 表中GC暂停时间的单位为毫秒。
    • 当堆容量为128MB时,堆空间资源很紧张,对于 UseSerialGC, UseParallelGC 和 UseConcMarkSweep 3种设置,后期老年代空间使用率接近100%,而年轻代使用率也在90%以上。对于 UseG1GC 设置则发生内存溢出错位。
    • 对于 UseConcMarkSeeepGC 设置,其GC暂停时间中的 “cms: 5” 指CMS收集器的初始标记和最终标记2步骤(CMS收集器只在这2个步骤暂停应用线程)花费时间之和。

    表3 不同垃圾收集器设置的应用业务吞吐量对比

    堆容量(MB) -XX:+UseSerialGC -XX:+UseParallelGC -XX:+UseConcMarkSeeepGC -XX:+UseG1GC
    1024 2002,2730,2473 2410,3269,3053 2967,3081,3049 3042,3460,3226
    512 2709,2904,2826 3083,3615,3396 3083,3200,3151 2985,3319,3162
    256 2570,2689,2615 2270,2551,2372 2176,2883,2583 2616,2871,2752

    说明:

    • 表中数据来源于运行 GCLogAnalysis 类
    • -Xms 和 -Xmx 参数都等于堆容量。
    • 表中数值表示应用生成对象的总次数,该次数一定程度上可以代表应用业务吞吐量。3个值分别代表最小值、最大值、平均值。

    根据表2和表3,可以得出以下结论:
    1 在GC暂停时间方面
    1.1 对比 -XX:+UseSerialGC 和 -XX:+UseParallelGC,后者优势明显,特别是对于 minor gc(年轻代gc)
    1.2 对比 -XX:+UseParallelGC 和 -XX:UseConcMarkSweep,对于 minor gc,二者无明显差别。而对于老年代gc,CMS收集器的并发机制使得GC暂停时间只有5ms左右,明显优于前者。
    1.3 G1收集器 的GC暂停时间可稳定保持在50ms以内,且很多时候只有5-20ms,十分出色。
    1.4 大体上,对于每种垃圾收集器,堆容量越大,GC暂停时间越大,这是因为堆容量越大,每次要收集的垃圾越多。不过这种现象在CMS收集器和G1收集器上不太显著。
    1.5 相对其他收集器,G1收集器占用更多额外内存。理由是当堆容量为128MB时,使用G1收集器会发生内存溢出错位,而其他收集器则不会或发生的概率较小。
    2 在吞吐量方面
    2.1 对比 -XX:+UseSerialGC 和 -XX:+UseParallelGC,在堆充足的情况下,后者优势比较明显,而在堆紧张的情况下,后者反而不如前者。
    2.2 对比 -XX:+UseParallelGC 和 -XX:UseConcMarkSweep,二者无明显差别。
    2.3 相对其他收集器,G1收集器的吞吐量始终保持不错。
    2.4 对于 -XX:+UseSerialGC, -XX:+UseParallelGC 和 -XX:UseConcMarkSweep 3种设置,在堆充足的情况下,继续加大堆,可能反而使吞吐量下降。