Serial是一个新生代单线程收集器,在收集的时候会Stop The World!,也就是停止一切用户工作的线程。 新生代采用标记-复制算法来清理垃圾。 老年代(SerialOld)采用标记-整理来清理垃圾。 优点:
适合用于客户端模式下的虚拟机。
缺点:
ParNew可以看做是Serial的多线程并行版本,除了使用多线程收集外,其余行为与Serial完全一致。也是新生代收集器 ParNew在新生代采用标记-复制算法。
ParNew除了比Serial多了多线程并行收集外,并没有什么特别的创新的地方。 除了Serial只有ParNew能和CMS配合。
优点:
缺点:
Parallel Scavenge也是一个新生代收集器,同样基于标记-复制算法,多线程并行收集。 Parallel Scavenge对比ParNew的特别之处在于Parallel Scavenge注重于达到一个可控制的吞吐量。 吞吐量:用户代码运行时间比处理器运行总时间。
比如一个程序运行100分钟,用户使用99分钟,垃圾收集1分钟。吞吐量即为99%。 停顿时间越短越适合与用户的交互,保证服务响应质量的程序。 高吞吐量则可以高效利用处理器资源,尽快完成程序的计算任务,主要适合在后台运算而不太需要交互的分析任务。
Parallel 有一个 -XX:+UseAdaptiveSizePolicy 参数可以不需要人工指定新生代大小、Eden、Survivor区的比例,晋升老年代对象的大小等细节参数。虚拟机会根据当前性能情况,动态调整这些参数以提供合适的停顿时间或者最大吞吐量。这种调节方式被称为自适应的调节策略。
如果用户对收集器的运作不太了解手动优化存在困难使用Parallel配合自适应调节策略,把内存管理调度交给虚拟机是个不错的选择。
优点:
缺点:
Serial的老年代版本,同样是单线程,标记-整理算法收集。
这个收集器的主要意义也是供客户端模式下的HotSpot使用。
优缺点与Serial一样
Parallel的老年代版本收集器,支持多线程并发收集,标记-整理算法收集。 可与Parallel Scavenge配合。
优缺点与Parallel一样
CMS收集器是一种以获取最短停顿时间为目标的收集器,目前很大一部分Java应用集中在互联网中或者浏览器的B/S系统服务端上,这类应用通常比较关注服务的响应速度,希望系统停顿时间尽可能短,可以给用户带来更好的体验,CMS就非常适合这类应用的需求。
CMS是根据标记-清除算法实现的,它的运作过程分为以下四个步骤:
其中初始标记和重新标记都是需要暂停用户操作的,初始标记就是标记能够GC Roots关联到的对象,速度很快。并发标记就是从GC Roots标记的对象开始遍历整个对象图,并发标记的过程比较漫长,用户可以进行操作。重新标记就是找出在并发标记时发生变动的对象,这一步时间稍长但也比并发标记短很多。并发清除就是清楚那些已经判断死亡的对象,同样用户可以操作。
优点:
不足:
G1收集器是一款面向服务端应用的垃圾收集器,目前是JDK9的默认垃圾收集器。与其他收集器相比,G1具有如下特点:
G1收集器将这个Java堆划分为多个大小相等的独立区域(Region),虽然还保留有新生代和老年代的概念,但两者之间不是物理隔离的。他们都是一部分Region的集合。
每一个方块就是一个区域,每个区域可能是 Eden、Survivor、老年代,每种区域的数量也不一定。JVM 启动时会自动设置每个区域的大小(1M ~ 32M,必须是 2 的次幂),最多可以设置 2048 个区域(即支持的最大堆内存为 32M*2048 = 64G),假如设置 -Xmx8g -Xms8g,则每个区域大小为 8g/2048=4M。
G1收集器可以有计划地避免在整个Java堆全区域的垃圾收集。G1可以跟踪各个Region里面垃圾堆积的价值大小(回收所获得的空间大小及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,收集加载最大的region,这种方式保证了有限时间内可以获取尽可能多高的收集效率。
为了在 GC Roots Tracing 的时候避免扫描全堆,在每个 Region 中,都有一个 Remembered Set 来实时记录该区域内的引用类型数据与其他区域数据的引用关系(在前面的几款分代收集中,新生代、老年代中也有一个 Remembered Set 来实时记录与其他区域的引用关系),在标记时直接参考这些引用关系就可以知道这些对象是否应该被清除,而不用扫描全堆的数据。
G1收集器收集器收集过程有初始标记、并发标记、最终标记、筛选回收,和 CMS 收集器前几步的收集过程很相似。
在收集器的语境中: ·并行(Parallel):并行描述的是多条垃圾收集器线程之间的关系,说明同一时间有多条这样的线 程在协同工作,通常默认此时用户线程是处于等待状态。 ·并发(Concurrent):并发描述的是垃圾收集器线程与用户线程之间的关系,说明同一时间垃圾 收集器线程与用户线程都在运行。由于用户线程并未被冻结,所以程序仍然能响应服务请求,但由于 垃圾收集器线程占用了一部分系统资源,此时应用程序的处理的吞吐量将受到一定影响。