赞
踩
在 JDK 1.5 时期,HotSpot 推出了一款在强交互应用中几乎可认为有划时代意义的垃圾收集器:CMS(Concurrent-Mark-Sweep)收集器,这款收集器是 HotSpot 虚拟机中第一款真正意义上的并发收集器,它第一次实现了让垃圾收集线程与用户线程同时工作。
CMS 的垃圾收集算法采用标记-清除算法,并且也会"Stop-The-World"
CMS 整个过程比之前的收集器要复杂,整个过程分为4个主要阶段,即初始标记阶段、并发标记阶段、重新标记阶段和并发清除阶段。(涉及STW的阶段主要是:初始标记 和 重新标记)
尽管 CMS 收集器采用的是并发回收(非独占式),但是在其初始化标记和再次标记这两个阶段中仍然需要执行“Stop-the-World”机制暂停程序中的工作线程,不过暂停时间并不会太长,因此可以说明目前所有的垃圾收集器都做不到完全不需要“stop-the-World”,只是尽可能地缩短暂停时间。
由于最耗费时间的并发标记与并发清除阶段都不需要暂停工作,所以整体的回收是低停顿的
CMS 收集器的垃圾收集算法采用的是标记-清除算法
HotSpot 有这么多的垃圾回收器,那么如果有人问,Serial GC、Parallel GC、Concurrent Mark Sweep GC 这三个 GC 有什么不同呢?
G1(Garbage-First)是一款面向服务端应用的垃圾收集器,主要针对配备多核 CPU 及大容量内存的机器
是 JDK 9 以后的默认垃圾回收器
G1 所谓的分代,已经不是下面这样的了
而是这样的一个区域
G1回收器 Region 之间是复制算法,但整体上实际可看作是标记-压缩(Mark-Compact)算法
这是 G1 相对于 CMS 的另一大优势,G1 除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为 M 毫秒的时间片段内,消耗在垃圾收集上的时间不得超过 N 毫秒。
与其他 GC 收集器相比,G1 使用了全新的分区算法,其特点如下所示:
G1 的设计原则就是简化 JVM 性能调优,开发人员只需要简单的三步即可完成调优:
G1 中提供了三种垃圾回收模式:YoungGC、Mixed GC 和Full GC,在不同的条件下被触发。
面向服务端应用,针对具有大内存、多处理器的机器。(在普通大小的堆里表现并不惊喜)
最主要的应用是需要低 GC 延迟,并具有大堆的应用程序提供解决方案;
如:在堆大小约 6GB 或更大时,可预测的暂停时间可以低于0.5秒;(G1 通过每次只清理一部分而不是全部的Region 的增量式清理来保证每次 GC 停顿时间不会过长)。 用来替换掉 JDK 1.5 中的 CMS 收集器;
在下面的情况时,使用 G1 可能比 CMS 好:
HotSpot 垃圾收集器里,除了 G1 以外,其他的垃圾收集器使用内置的 JVM 线程执行 GC 的多线程操作,而 G1 GC 可以采用应用线程承担后台运行的 GC 工作,即当 JVM 的 GC 线程处理速度慢时,系统会调用应用程序线程帮助加速垃圾回收过程。
每个 Region 都是通过指针碰撞来分配空间
G1 GC 的垃圾回收过程主要包括如下三个环节:
(如果需要,单线程、独占式、高强度的 Full GC 还是继续存在的。它针对 GC 的评估失败提供了一种失败保护机制,即强力回收。)
顺时针,Young GC -> Young GC + Concurrent Mark -> Mixed GC 顺序,进行垃圾回收。
举个例子:一个 Web 服务器,Java 进程最大堆内存为4G,每分钟响应1500个请求,每45秒钟会新分配大约2G的内存。G1 会每45秒钟进行一次年轻代回收,每31个小时整个堆的使用率会达到45%,会开始老年代并发标记过程,标记完成后开始四到五次的混合回收。
一个对象被不同区域引用的问题
一个 Region 不可能是孤立的,一个 Region 中的对象可能被其他任意 Region 中对象引用,判断对象存活时,是否需要扫描整个 Java 堆才能保证准确?
在其他的分代收集器,也存在这样的问题(而 G1 更突出)回收新生代也不得不同时扫描老年代?这样的话会降低 Minor GC 的效率;
无论 G1 还是其他分代收集器,JVM 都是使用 Remembered Set 来避免全局扫描:
截止 JDK 1.8,一共有7款不同的垃圾收集器。每一款的垃圾收集器都有不同的特点,在具体使用的时候,需要根据具体的情况选用不同的垃圾收集器。
GC 发展阶段:Serial => Parallel(并行)=> CMS(并发)=> G1 => ZGC
不同厂商、不同版本的虚拟机实现差距比较大。HotSpot 虚拟机在 JDK7/8 后所有收集器及组合如下图
Java 垃圾收集器的配置对于 JVM 优化来说是一个很重要的选择,选择合适的垃圾收集器可以让 JVM 的性能有一个很大的提升。怎么选择垃圾收集器?
最后需要明确一个观点:
没有最好的收集器,更没有万能的收集
调优永远是针对特定场景、特定需求,不存在一劳永逸的收集器
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。