天天看点

Java 常见的垃圾回收器

Java 常见的垃圾回收器

垃圾回收器 (GC, Garbage Collector)是和具体的 JVM 实现紧密相关。

Java 虚拟机针对新生代和年老代分别提供了多种不同的垃圾收集器。

Java 常见的垃圾回收器
垃圾收集器

Serial GC

Serial GC ,是新生代的垃圾回收器, Serial 体现在其收集工作是单线程的,并且在垃圾收集过程中,其他线程阻塞,进入 Stop Thre World 状态。新生代使用的 Serial 垃圾回收器,是基于复制算法的。

-XX:+UseSerialGC
           

Paralel Scavenge

Parallel Scavenge 收集器,是一个新生代的垃圾回收器,采用的是复制算法。关注的是程序到达一个可控制的吞吐量(Thoughput ,CPU 用于运行用户代码的时间/CPU总消耗时间)。吞吐量= 运行用户代码时间/(运行用户代码时间+垃圾收集时间). 高吞吐量可以最高效率的利用 CPU  时间。尽快完成程序的运算任务。值得关注的是 Parallel Scavenge 收集器有个自适应调节参数。

这个参数就是:-XX:UseAdaptiveSizePolic。这是一个开关参数,当这个开关打开之后,就不需要手动指定新生代的大小(-Xmn)、Eden与Survivor区的比列(-XX:SurvivorRatio)、晋升老年代对象大小(-XX:PertenureSizeThreshold)等参数细节了,虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或者最大的吞吐量。

-XX:+UseParallelGC
           

可以直接设置暂停时间或者吞吐量等目标, JVM 会自动进行适应性调整。

-XX:MaxGCPauseMillis=value
-XX:GCTimeRatio=N // GC时间和用户时间比例 = 1 / (N+1)
           

ParNew

ParNew 垃圾回收器是 Serial 收集器的多线程版本。采用的也是复制算法。包括 Serial 收集器可用的所有控制参数。也就是说可并行的进行垃圾回收。

可通过-XX:ParallelGCThreads 参数来限制垃圾收集器的线程数。

Java 常见的垃圾回收器
 -XX:+UseParNewGC
           

Serial Old

Serial Old 是 Serial 垃圾收集器的老年代版本,同样是个单线程的收集器,是基于标记-整理算法。

Java 常见的垃圾回收器

Parallel Old

Parallel Old 是 Parallel Scavenge 的老年代版本,使用的是多线程-标记整理算法。JDK1.6 才开始使用。ParallelScavenge 是可以保证新生代的吞吐量优先,但是不能保证整体吞吐量。Parallel Old 是为了在老年代同样提供吞吐量优先的垃圾回收器。

Java 常见的垃圾回收器

ParallelOld

CMS

CMS 是基于标记清除算法,设计的目的是减少停顿时间。基于标记清除算法,会存在内存碎片化的问题。

-XX:+UseConcMarkSweepGC
           

CMS 处理流程

  1. 初始标记(CMS-initial-mark) ,会导致stw;
  2. 并发标记(CMS-concurrent-mark),与用户线程同时运行;
  3. 重新标记(CMS-remark) ,会导致swt;
  4. 并发清除(CMS-concurrent-sweep),与用户线程同时运行;
  5. 并发重置状态等待下次CMS的触发(CMS-concurrent-reset),与用户线程同时运行;
Java 常见的垃圾回收器

CMS处理流程

G1

G1 本质上是一个分带垃圾回收器。 Garbage First 垃圾回收器相对 CMS 垃圾回收器,有两个改进:

  1. 基于标记-整理 算法,不产生内存碎片。
  2. 可以准确的控制停顿时间,在不牺牲吞吐的情况下实现低停顿的垃圾回收。

G1 为了避免全区域垃圾收集,把堆内存划分为大小固定的几个独立区域,并跟踪这些区域的回收进度。同时在后台维护一个优先列表,每次根据收集时间的,优先回收垃圾最多的区域。

G1 引入了额外的概念,Region。G1垃圾回收器把堆划分成一个个大小相同的Region。在HotSpot的实现中,整个堆被划分成2048左右个Region。每个Region的大小在1-32MB之间,具体多大取决于堆的大小。

G1垃圾回收器的分代也是建立在这些Region的基础上的。对于Region来说,它会有一个分代的类型,并且是唯一一个。即,每一个Region,它要么是young的,要么是old的。还有一类十分特殊的Humongous。所谓的Humongous,就是一个对象的大小超过了某一个阈值——HotSpot中是Region的1/2,那么它会被标记为Humongous。如果我们审视HotSpot的其余的垃圾回收器,可以发现这种对象以前被称为大对象,会被直接分配老年代。而在G1回收器中,则是做了特殊的处理。

Java 常见的垃圾回收器

image

Java 常见的垃圾回收器

https://mp.weixin.qq.com/s/QQwzdVooFcjaeTHSsGoKbg