垃圾回收器和内存分配
垃圾回收器可不仅仅只有一种,什么情况下使用哪一种,对性能又有什么影响,我们应该了解。
一:串行回收器
1、新生代串行回收器
最古老,最基本的垃圾回收器一种。
特点: 1、它仅仅使用单线程进行垃圾回收。
2、它是独占式的垃圾回收。
在串行回收器运行时,应用程序中的所有线程都停止工作,进行等待,这种现象称为“Stop-The-World”
参数:
-XX:+UseSerialGC 指定使用新生代串行收集器和老年代串行收集器。当虚拟机在client模式下,它是默认的垃圾回收器。
注意:
串行垃圾回收器虽然古老,但是久经考验。在大多数情况下,其性能表现是想但不错的。
2、老年代串行回收器
老年代串行回收器使用标记压缩算法,是一种串行,独占式的垃圾回收器。在堆较大时,会出现较长的停顿时间,作为老牌的垃圾回收器,老年代串行回收器可以和多种新生代回收器配合使用,同时它也可以作为CMS的备用回收器。
参数:
-XX:+UseSerialGC 指定使用新生代串行收集器和老年代串行收集器。
-XX:+UseParNewGC 新生代使用ParNew回收器,老年代使用串行回收器。
-XX:+UseParallelGC 新生代使用ParallelGC回收器,老年代使用串行回收器。
eg:
[GC[DefNew: 31432K->4287K(38784K), 0.0066479 secs] 31432K->4636K(124992K), 0.0066786 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
二、并行回收器
并行回收器在串行回收器的基础上做了改进,它使用多个线程同时进行垃圾回收,对于并行能力强的计算机。可以有效缩短垃圾回收所需的时间。
1、新生代parNew回收器
只是简单的将串行回收器多线程化,它的回收策略、算法以及参数和新生代串行回收器一样,在并发能力较强的CPU上,它产生的停顿时间要短于串行回收器。
参数:
-XX:+UseParNewGC 新生代使用ParNew回收器,老年代使用串行回收器。
-XX:+UseConcMarkSweepGC 新生代使用ParNew回收器,老年代使用CMS。
eg:
[GC[ParNew: 31432K->4288K(38784K), 0.0059379 secs] 31432K->4670K(124992K), 0.0059722 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
-XX:ParallelGCThreads 指定工作时的线程总数,一般最好与CPU相当,避免过多的线程数,影响垃圾回收性能。cpu数量大于8时,线程数等于3+((5*CPU_COUNT)/8),小于8时,线程数等于CPU数量。
2、新生代ParallelGC回收器
使用复制算法,它和ParNew回收器一样,都是多线程、独占式的回收器。但是,ParallelGC回收器有一个重点的特点:它非常关注系统的吞吐量。
参数:
-XX:+UseParallelGC 新生代使用ParallelGC回收器,老年代使用串行回收器
-XX+UseParallelOldGC 新生代使用ParallelGC回收器,老年代使用ParallelOldGC回收器。
ParallelGC提供两个重要参数用于控制系统的吞吐量
-XX:MaxGCPauseMillis 设置最大垃圾回收停顿时间。它的值是一个大于0的整数。
-XX:GCTimeRatio 设置吞吐量大小,他的值是一个0到100之间的整数,假设GCTimeRatio值为n,那么系统将花费1/(1+n)的时间用于垃圾回收。
假设取值为19是,1/(1+19)=5%,即5%的时间用于垃圾收集。
eg:[GC [PSYoungGen: 31334K->4792K(38400K)] 31334K->4792K(124416K), 0.0122629 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
3、老年代ParallelOldGC回收器
使用标记压缩,是一种多线程并发的收集器。和新生代ParallelGC回收器一样,它是一种关注吞吐量的收集器,用于老年代。
-XX:+UseParallelOldGC可以在新生代使用ParallelGC的情况下,老年代使用ParallelOldGC
-XX:ParallelGCThreads也可以用于设置垃圾回收时的线程数量
三、CMS回收器
CMS回收器关注于系统停顿时间。CMS是Concurrent Mark Sweep的缩写,意为并发标记清除,从名称上就可以得知,它使用的是标记清除算法,同时它又是一个使用多线程并行回收的垃圾回收器。从整体上说CSM收集不是独占式的,它可以在应用程序运行过程中进行垃圾回收。
工作流程:
在此过程中,并发标记,并发清理和并发重置都是可以和应用程序线程一起执行的。整个CMS回收过程中,默认情况下,在并发标记之后,会有一个预清理的操作(也可以关闭-XX:-CMSPrecleaningEnabled,不进行预清理),预清理还会尝试控制一次停顿时间。
参数:
-XX:+UseConcMarkSweepGC CMS是多线程回收器,设置合理的线程数影响性能
-XX:ConcGCThreads或者-XX:ParallelCMSThreads 参数手工设定
-XX:CMSInitiatingOccupancyFraction 设置回收阀值
-XX:+UseCMSCompactAtFullCollection 可以在CMS垃圾回收完以后进行一次内存碎片整理,内存碎片整理不是并发的。
有关Class的回收
在使用CMS回收器时,如果需要回收Perm区,那么默认情况下,还是需要一次Full GC.