GC之ParNew收集器
PS:堆内存是指JVM的内存大小包括堆区和非堆区;
-server 服务器模式运行,-client表示客户端运行模式;
-Xms1G 最小JAVA虚拟机内存1G,是JVM的内存大小而不是堆区的大小;
-Xmx2G 最大JAVA虚拟机内存2G,是JVM的内存大小而不是堆区的大小;
What(是什么)
ParNew收集器是JAVA虚拟机中垃圾收集器的一种。它是Serial收集器的多线程版本,除了使用多条线程进行垃圾收集之外,其余行为包括Serial收集器可用的所有控制参数(例如:-XX:SurvivorRatio、-XX:PretenureSizeThreshold、-XX:HandlePromotionFailure等)、收集算法、Stop The World、对象分配规则、回收策略等都与Serial收集器一致。
Why(为什么)
需要注意的是,ParNew在单核甚至双核环境下绝对不会有比Serial收集器更好的效果,但是随着CPU数量的增加ParNew相较于Serial的优势会越来越明显,但并不是成倍增长的,原因还是那个,多线程切换的开销。
How(怎么做)
- 使用方式:-XX:+UseParNewGC,打开该开关后,使用ParNew(年轻代)+Serial Old(老年代)组合进行GC。另外,ParNew是CMS收集器的默认年轻代收集器。
- ParNew用于垃圾回收的线程可用参数-XX:ParallelGCThreads=n进行配置,建议n与主机逻辑cpu数一致。ParNew是许多运行在Server模式下的虚拟机中首选的新生代收集器,在JDK1.6以及之前的版本中,除了Serial收集器外,只有它能与CMS收集器配合工作。
- 除了多线程外,其余的行为、特点和Serial收集器一样;如Serial收集器可用控制参数、收集算法、Stop The World、内存分配规则、回收策略等;两个收集器共用了不少代码。
- ParNew/Serial Old组合收集器运行示意图如下:
- 应用场景:在Server模式下,ParNew收集器是一个非常重要的收集器,因为除了Serial收集器外,目前只有它能与CMS收集器配合工作;但在单个CPU环境中,不会比Serail收集器有更好的效果,因为存在线程交互开销。
- 设置参数:
"-XX:+UseConcMarkSweepGC":指定使用CMS后,会默认使用ParNew作为新生代收集器;
"-XX:+UseParNewGC":强制指定使用ParNew;
"-XX:ParallelGCThreads":指定垃圾收集的线程数量,ParNew默认开启的收集线程与CPU的数量相同;
- 设置参数:
- 为什么只有ParNew能与CMS收集器配合:
CMS是HotSpot在JDK1.5推出的第一款真正意义上的并发(Concurrent)收集器,第一次实现了让垃圾收集线程与用户线程(基本上)同时工作;
CMS作为老年代收集器,但却无法与JDK1.4已经存在的新生代收集器Parallel Scavenge配合工作;这是因为Parallel Scavenge(以及G1)都没有使用传统的GC收集器代码框架,而另外独立实现,而其余几种收集器则共用了部分的框架代码。
- 为什么只有ParNew能与CMS收集器配合:
补充
ParNew收集器和Serial收集器的差异
ParNew收集器在单CPU的环境中绝对不会有比Serial收集器更好的效果,甚至由于存在线程交互的开销,该收集器在通过超线程技术实现的两个CPU的环境中都不能百分之百地保证能超越Serial收集器。当然,随着可以使用的CPU的数量的增加,它对于GC时系统资源的利用还是很有好处的。它默认开启的收集线程数与CPU的数量相同,在CPU非常多(譬如32个,现在CPU动辄就4核加超线程,服务器超过32个逻辑CPU的情况越来越多了)的环境下,可以使用-XX:ParallelGCThreads参数来限制垃圾收集的线程数。
并行和并发的区别
- 并行(Parallel):指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。
- 并发(Concurrent):指用户线程与垃圾收集线程同时执行(但不一定是并行的,可能会交替执行),用户程序继续运行,而垃圾收集程序运行于另一个CPU上。
[GC [ParNew 表示新生代使用的是ParNew收集器。
[GC [DefNew 表示新生代使用的是Serial收集器。