JVM-055-垃圾回收器-CMS回收器(低延时)

引入

  • 在JDK1.5时期,Hotspot推出了一款在强交互应用中几乎可认为有划时代意义的垃圾收集器:CMS(Concurrent-Mark-Sweep)收集器,这款收集器是HotSpot虚拟机中第一款真正意义上的并发收集器,它第一次实现了让垃圾收集线程与用户线程同时工作。
  • CMS收集器的关注点是尽可能缩短垃圾收集时用户线程的停顿时间。停顿时间越短(低延迟)就越适合与用户交互的程序,良好的响应速度能提升用户体验。
    • 目前很大一部分的Java应用集中在互联网站或者B/S系统的服务端上,这类应用尤其重视服务的响应速度,希望系统停顿时间最短,以给用户带来较好的体验。CMS收集器就非常符合这类应用的需求。
  • CMS的垃圾收集算法采用标记-清除算法,并且也会”Stop-the-World”
  • 不幸的是,CMS作为老年代的收集器,却无法与JDK1.4.0中已经存在的新生代收集器Parallel Scavenge配合工作(因为实现的框架不一样,没办法兼容使用),所以在JDK1.5中使用CMS来收集老年代的时候,新生代只能选择ParNew或者Serial收集器中的一个。
  • 在G1出现之前,CMS使用还是非常广泛的。一直到今天,仍然有很多系统使用CMS GC。
阅读更多

JVM-054-垃圾回收器-Parallel Scavenge回收器(吞吐量优先)

引入

HotSpot的年轻代中除了拥有ParNew收集器是基于并行回收的以外,Parallel Scavenge收集器(简称Parallel收集器)同样也采用了复制算法、并行回收和”Stop the World”机制

与ParNew比较

那么Parallel收集器的出现是否多此一举?

  • 和ParNew收集器不同,Parallel Scavenge收集器的目标则是达到一个可控制的吞吐量(Throughput),它也被称为吞吐量优先的垃圾收集器。
  • 自适应调节策略也是Parallel Scavenge与ParNew一个重要区别。(动态调整内存分配情况,以达到一个最优的吞吐量或低延迟)

说明

  • 高吞吐量则可以高效率地利用CPU时间,尽快完成程序的运算任务,主要适合在后台运算而不需要太多交互的任务。因此,常见在服务器环境中使用。例如,那些执行批量处理、订单处理、工资支付、科学计算的应用程序。

  • Parallel 收集器在JDK1.6时提供了用于执行老年代垃圾收集的 Parallel Old 收集器,用来代替老年代的Serial Old收集器。

  • Parallel Old收集器采用了标记-压缩算法,但同样也是基于并行回收和”Stop-the-World”机制

  • 在程序吞吐量优先的应用场景中,Parallel收集器和Parallel Old收集器的组合,在server模式下的内存回收性能很不错。

  1. 在Java8中,默认是此垃圾收集器。

图示

相关JVM参数

  1. -XX:+UseParallelGC

    手动指定年轻代使用Parallel并行收集器执行内存回收任务。

  2. -XX:+UseParallelOldGC

    手动指定老年代使用ParallelOld并行回收收集器。

上面两个参数分别适用于新生代和老年代。jdk8是默认开启的。默认开启一个,另一个也会被开启。(互相激活)

  1. -XX:ParallelGCThreads

    设置年轻代并行收集器的线程数。一般地,最好与CPU数量相等,以避免过多的线程数影响垃圾收集性能。

    • 在默认情况下,当CPU数量小于8个,ParallelGCThreads的值等于CPU数量。

    • 当CPU数量大于8个,ParallelGCThreads的值等于3+[5*CPU_Count]/8]

  2. -XX:MaxGCPauseMillis

    设置垃圾收集器最大停顿时间(即STW的时间)。单位是毫秒。

    • 为了尽可能地把停顿时间控制在XX:MaxGCPauseMillis 以内,收集器在工作时会调整Java堆大小或者其他一些参数。
    • 对于用户来讲,停顿时间越短体验越好。但是在服务器端,我们注重高并发,整体的吞吐量。所以服务器端适合Parallel,进行控制。
    • 该参数使用需谨慎。
  3. -XX:GCTimeRatio

    垃圾收集时间占总时间的比例,即等于 1 / (N+1) ,用于衡量吞吐量的大小。

    • 取值范围(0, 100)。默认值99,也就是垃圾回收时间占比不超过1。
    • 与前一个-XX:MaxGCPauseMillis参数有一定矛盾性,STW暂停时间越长,Radio参数就容易超过设定的比例。
    • 如果把此参数设置为19,那允许的最大GC时间就占总时间的5%(即1/(19+1)),默认值为99,就是允许最大1%(即1/(99+1))的垃圾收集时间。

JVM-053-垃圾回收器-ParNew回收器(并行回收)

引入

  • 如果说Serial GC是年轻代中的单线程垃圾收集器,那么ParNew收集器则是Serial收集器的多线程版本。
    • Par意思是Parallel的缩写,New:意思是只能处理新生代
  • ParNew 收集器除了采用并行回收的方式执行内存回收外,两款垃圾收集器之间几乎没有任何区别。ParNew收集器在年轻代中同样也是采用复制算法、”Stop-the-World”机制
  • ParNew 是很多JVM运行在Server模式下新生代的默认垃圾收集器
阅读更多

JVM-050-垃圾回收器-评估GC的性能指标

指标

  1. 吞吐量:运行用户代码的时间占总运行时间的比例。

    • (总运行时间 = 程序的运行时间 + 内存回收的时间)
  2. 垃圾收集开销:吞吐量的补数,垃圾收集所用时间与总运行时间的比例。

  3. 暂停时间:执行垃圾收集时,程序的工作线程被暂停的时间。

  4. 收集频率:相对于应用程序的执行,收集操作发生的频率。

  5. 内存占用:Java堆区所占的内存大小。

  6. 快速:一个对象从诞生到被回收所经历的时间。

阅读更多

JVM-049-垃圾回收器-概述与分类

垃圾回收器概述

  • 垃圾收集器没有在规范中进行过多的规定,可以由不同的厂商、不同版本的JVM来实现。

  • 由于JDK的版本处于高速迭代过程中,因此Java发展至今已经衍生了众多的GC版本。

  • 从不同角度分析垃圾收集器,可以将GC分为不同的类型。

阅读更多

JVM-048-垃圾回收-相关概念的概述-在谈引用

引入

我们希望能描述这样一类对象:当内存空间还足够时,则能保留在内存中;如果内存空间在进行垃圾收集后还是很紧张,则可以抛弃这些对象。

在JDK1.2版之后,Java对引用的概念进行了扩充,将引用分为:

  • 强引用(Strong Reference)
  • 软引用(Soft Reference)
  • 弱引用(Weak Reference)
  • 虚引用(Phantom Reference)

这4种引用强度依次逐渐减弱。

除强引用外,其他3种引用均可以在java.lang.ref包中找到它们的身影。如下图,显示了这3种引用类型对应的类,开发人员可以在应用程序中直接使用它们。

阅读更多

JVM-047-垃圾回收-相关概念的概述-安全点与安全区域

安全点(Safepoint)

概念

程序执行时并非在所有地方都能停顿下来开始GC,只有在特定的位置才能停顿下来开始GC,这些位置称为“安全点(Safepoint)”。

Safe Point的选择很重要,如果太少可能导致GC等待的时间太长,如果太频繁可能导致运行时的性能问题。大部分指令的执行时间都非常短暂,通常会根据“是否具有让程序长时间执行的特征”为标准。比如:选择一些执行时间较长的指令作为Safe Point,如方法调用、循环跳转和异常跳转等。

阅读更多

JVM-046-垃圾回收-相关概念的概述-并行与并发

程序的并发与并行

并发(Concurrent)

概念

  • 在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理器上运行

  • 并发不是真正意义上的“同时进行”,只是CPU把一个时间段划分成几个时间片段(时间区间),然后在这几个时间区间之间来回切换。由于CPU处理的速度非常快,只要时间间隔处理得当,即可让用户感觉是多个应用程序同时在进行

阅读更多