《深入java虚拟机》读书笔记之垃圾收集器与内存分配策略 (4)

Serial虽然存在上面的问题,但是这并不表示它是一个无用的收集器,反而到目前为止Serial收集器在Client模式下被用在新生代的收集(64位虚拟机默认支持Server模式,并且无法切换;32位虚拟机可在Client和Server之间切换。正常情况下,Server模式启动较慢,但启动后性能远高于Client模式)。但是实际上使用也不多了。。。

Serial收集器的优点在于:在单CPU环境中,由于Serial由于没有线程的开销,专心做垃圾回收自然能获得极高的回收效率。

ParNew收集器

ParNew实际上就是一个多线程版的Serial收集器,除了多线程进行垃圾回收外其他都和Serial基本一致。

ParNew在很多运行于Server模式下的虚拟机中被用于新生代的首选。最大的原因在于目前为止只有其能CMS(Concurrent Mark Sweep)收集器配合使用。

并发与并行

并发:简单来讲是指一个处理器在同一时间间隔处理多个任务。放到垃圾回收这里指垃圾回收线程和用户工作线程同时进行工作。

并行:并行是指多个处理器在同一时刻处理多个任务。放到垃圾回收这里指多个垃圾回收线程同时工作,但是用户工作线程处于等待状态。

Parallel Scavenge收集器

Parallel Scavenge是一个新生代的收集器,同时它是一个并行的多线程的收集器,其使用复制算法。Parallel Scavenge的目标是达到一个可控制的吞吐量(throughput)。

吞吐量:CPU用于运行用户代码的时间和CPU总共运行时间的比值

吞吐量越高表示停顿时间短,程序响应速度快,CPU利用率越高。

Parallel Scavenge提供了几个用于精确控制吞吐量的参数:

-XX:MaxGCPauseMillis:控制最大垃圾收集停顿时间,该参数的值运行为一个大于0的毫秒数,虚拟机会尽量将垃圾回收花费的时间控制在设定的值之下。但是并不代表将每次垃圾回收的时间减小就一定是有利的,因为回收时间的降低是以降低吞吐量和新生代空间为代价的。为了保证每次垃圾回收的时间减小,就需要降低每一次垃圾回收的区域,所以需要减小新生代的大小。但在降低新生代大小的同时也增加了垃圾回收的次数。所以在设置该值是不能盲目的追求小的回收时间,而应该根据项目实际情况进行设置。

-XX:GCTimeRatio:直接设置吞吐量大小。该值代表吞吐量比率,所以其应该是一个大于0并且小于100的数,这里还要求其为整数。

-XX:UseAdaptiveSizePolicy:用于确定是否开启GC自适应的调整策略,如果打开该策略,就不需要手工指定新生代的大小(-Xmn)、Eden区和Survivor区的比例(-XX:SurvivorRatio)、晋升老年代年龄(-XX:PretentureSizeThreshold)等参数。虚拟机会监控当前系统运行状态收集性能监控信息,自动的调整系统中垃圾回收停顿时间或者最大的吞吐量。该方式适合不太清楚如何设置上面那些参数的同学。

Serial Old

Serial Old是Serial的老年代版本,它也是一个单线程收集器,使用“标记-整理”算法。它的作用主要是两个:一个是搭配Parallel Scavenge收集器使用;另外就是当CMS收集器发生Concurrency Mode Failure时作为备用收集器。

Parallel Old

同Serial Old一样,Parallel Old是Parallel Scavenge的老年代版本。在注重吞吐量和CPU资源敏感的地方都可以优先考虑Parallel Old可以和Parallel Scavenge一起搭配使用。

CMS收集器

CMS(Concurrency Mark Sweep)是一个以获取最短回收停顿时间为目标的收集器,允许垃圾回收线程和用户工作线程同时运行。其使用“标记-清除”算法。目前来说例如淘宝等大型互联网企业都希望请求响应时间能尽量短,并且垃圾回收的停顿时间也尽量短,这种情况就可以使用CMS收集器。

CMS的“标记-清除”算法分为多个步骤:

初始标记:初始标记是用于标记直接与GC Roots关联的对象,不需要遍历下去,所需的时间很短。这一过程会发生STW(Stop the World)。

并发标记:并发标记就是遍历所有与GC Roots直接或者间接关联的对象。

重新标记:前面说过CMS允许垃圾回收线程和用户工作线程同时运行,所以这一过程是为了标记在前面标记过程中发生变动的对象。这一过程会发生STW(Stop the World)。

并发清除:清除掉那些没有被标记的对象。

其中并发标记和并发清除过程耗费时间最长,但是这两个阶段都可以并发进行,所以对用户的影响也不会太大。

虽然CMS确实是一款很不错的垃圾收集器,但是其也还有几个缺点:

CMS收集器对CPU资源非常敏感。在并发阶段,它虽然不会导致用户线程停顿,但是会因为占用了一部分线程而导致应用程序变慢,总吞吐量会降低。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zygpfp.html