JVM垃圾收集器

参考文献:周志明《深入理解Java虚拟机》第二版

垃圾收集器就是 GC 具体的实现,不同厂商,不同版本,针对虚拟机不同的分区都有不一样垃圾收集器

图. 基于JDK 1.7 update 14的 HotSpot虚拟机包含的收集器

Serial 收集器

这个收集器是一个单线程收集器,在它进行收集工作时,必须暂停其他所有的工作线程,直到收集结束,这种工作方式又被称为“Stop the World”
它采用复制算法
因为单线程,所以会造成停顿,但也使得它简单而高效
适用于新生代 Minor GC
是运行在 Client 模式下的虚拟机的一个最佳选择

Serial Old 收集器

它是 Serial 收集器的老年代版本,也是一个 单线程 收集器
应用标记-整理算法
应用于老年代 Full GC
主要用于 Client 模式下

图. Serial / Serial Old收集器运行示意图

ParNew 收集器

它是 Serial 收集器的 多线程

注意区分:
并行(Parallel):指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态
并发(Concurrent):指用户线程与垃圾收集线程同时执行(但不一定是并行的,可能会交替执行),用户程序在继续执行,而垃圾收集程序运行在另一个CPU上

采用 收集算法
应用于新生代 Minor GC
适用于 Server 模式

图. ParNew / Serial Old 收集器运行示意图

Parallel Scavenge 收集器

它是一个 多线程 收集器
采用 复制算法
应用于新生代 Minor GC
特点:可控制吞吐量

吞吐量(Throughput):CPU 用于运行用户代码的时间与 CPU 总消耗时间的比值
吞吐量 = 运行代码时间 / (运行代码时间 + GC 时间)

提供设置参数:
-XX:MaxGCPauseMillis 控制最大 GC 停顿时间
-XX:GCTimeRatio 直接设置吞吐量大学
-XX:+UseAdaptiveSizePolic 动态自适应调整

它无法与 CMS 收集器配合工作,因为 CMS 收集器关注尽可能缩短 GC 时用户线程的停顿时间,与 Parallel Scavenge 的可控吞吐量不合

Parallel Old 收集器

它是 Parallel Scavenge 收集器的老年代版本
是一个 多线程 收集器
采用 标记-整理算法
应用于老年代 Full GC
经常与 Parallel Scavenge 配合,以充分达到“吞吐量优先”的作用

图. Parallel Scavenge / Parallel Old 收集器运行示意图

CMS 收集器

CMS(Concurrent Mark Sweep)收集器是一种以以获取最短回收停顿时间为目标的收集器
应用 标记-清除算法
它是一种 单线程与多线程结合使用 的收集器
收集步骤:

  1. 初始标记(CMS initial mark)
  2. 并发标记(CMS concurrent mark)
  3. 重新标记(CMS remark)
  4. 并发清除(CMS concurrent sweep)

初始标记、重新标记仍然要“Stop the world”
CMS 收集器最大的优点就是 大大减少了停顿时间
但是,它也有三个明显的缺点:

CMS 收集器对 CPU 资源敏感:它的并发清理虽然不会造成停顿,但是会占用 CPU 资源,导致用户程序变慢吞吐量低
CMS 收集器无法处理浮动垃圾(Floating Garbage):因为清理过程是并发的,所以在清理过程中用户也会产生垃圾,这些垃圾叫做浮动垃圾,CMS无法清理,只能等到下一次清理
③ CMS 应用“标记-清除算法”(为了快速),所以会造成空间碎片

图. CMS收集器运行示意图

G1 收集器

G1(Garbage-First)收集器可以说是目前最先进的收集器了,它具有如下特点:

  • 并行与并发
  • 分代收集
  • 空间整合
  • 可预测停顿

G1 收集器的先进之处在于,它几乎完全区别于以往收集器的思想,它改变了 Java 堆的格局,它将整个 Java 堆分为多个大小相等的独立区域(Region),虽然还保留有新生代和老年代的概念,但新生代与老年代不再是物理隔离的了,它们都是一部分 Region (不需要连续)的集合
G1 收集器能够预测停顿时间,是因为它可以有计划地避免在整个 Java 堆中进行全区域的垃圾收集,它跟踪各个 Region 里面的垃圾堆积的价值大小,在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的 Region

收集步骤:

  1. 初始标记(Initial Marking)
  2. 并发标记(Concurrent Marking)
  3. 最终标记(Final Marking)
  4. 筛选回收(Live Data Counting and Evavcuation)

前几步与 CMS 收集器非常相似,最后的筛选回收,就是从优先列表中根据预测停顿时间选择回收

图. G1 收集器运行示意图

G1 收集器非常先进而且非常复杂,可以说还处于试验阶段,并未完全成熟,目前主流的应用最多的收集器还是 CMS 收集器

时间: 2024-09-13 10:06:04

JVM垃圾收集器的相关文章

JVM垃圾收集器介绍

一.垃圾回收用到的主要算法 1.引用计数法 算法思路: 给对象中添加一个引用计数器,每当有一个地方引用他时,计数器值就加1:当引用失效时,计数器值就减1:当计数器的值为0时就可以把该对象删除. 算法优点: 实现简单,判定效率高 算法缺点: 难以解决对象之间相互循环引用的问题. 2.标记清除法 算法思路: 算法分为"标记"和"清除"两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象. 算法优点:     算法缺点: 效率低,标记和清除两个过程

jvm系列(三):GC算法 垃圾收集器

概述 垃圾收集 Garbage Collection 通常被称为"GC",它诞生于1960年 MIT 的 Lisp 语言,经过半个多世纪,目前已经十分成熟了. jvm 中,程序计数器.虚拟机栈.本地方法栈都是随线程而生随线程而灭,栈帧随着方法的进入和退出做入栈和出栈操作,实现了自动的内存清理,因此,我们的内存垃圾回收主要集中于 java 堆和方法区中,在程序运行期间,这部分内存的分配和使用都是动态的. 对象存活判断 判断对象是否存活一般有两种方式: 引用计数:每个对象有一个引用计数属性

深入理解JVM之四:详解垃圾收集器

前言 前面已经对垃圾收集算法有了较为详细的介绍,这里我们将对JVM中具体的垃圾回收器进行介绍,在虚拟机规范中并没有对垃圾回收器如何实现具体介绍,因此每个厂商的垃圾回收器可能会完全不同,但是我们介绍的是基于JDK1.7之后的Hotspot虚拟机(包括前面对Java虚拟机的介绍也是基于jdk1.7版本的).在Hotspot中,虚拟机的收集器主要有下: 可以看到垃圾收集器是按对象的分代来划分的,可以用线条连接的垃圾回收器表示两者可以配合使用.可以看到新生代垃圾收集器有Serial.ParNew.Par

[jjzhu学java]之深入理解JVM之垃圾收集器与内存分配策略

深入理解JVM之垃圾收集器与内存分配策略 如何判断对象已经消亡 引用计数算法 根搜索算法 引用 深入理解JVM之垃圾收集器与内存分配策略 java中对象的创建需要的内存都是在java堆中申请的,所以垃圾收集的区域就是对java堆和方法区的内存区域进行GC. 如何判断对象已经消亡 垃圾收集器的主要任务就是找出已经"消亡"的对象,将其标记并清除其说用内存的过程,如何判断某个对象已经"消亡",不同的虚拟机有不同的判断策略 引用计数算法 引用计数(Reference Cou

jvm系列(三):java GC算法 垃圾收集器

GC算法 垃圾收集器 概述 垃圾收集 Garbage Collection 通常被称为"GC",它诞生于1960年 MIT 的 Lisp 语言,经过半个多世纪,目前已经十分成熟了. jvm 中,程序计数器.虚拟机栈.本地方法栈都是随线程而生随线程而灭,栈帧随着方法的进入和退出做入栈和出栈操作,实现了自动的内存清理,因此,我们的内存垃圾回收主要集中于 java 堆和方法区中,在程序运行期间,这部分内存的分配和使用都是动态的.   对象存活判断 判断对象是否存活一般有两种方式: 引用计数:

[JVM]垃圾收集算法

本文"垃圾收集算法"节选自<深入理解Java虚拟机:JVM高级特性与最佳实践>[作者:周志明] 由于垃圾收集算法的实现涉及大量的程序细节,而且各个平台的虚拟机操作内存的方法又各不相同,因此本节不打算过多地讨论算法的实现,只是介绍几种算法的思想及其发展过程. 1 标记-清除算法 最基础的收集算法是"标记-清除"(Mark-Sweep)算法,如它的名字一样,算法分为"标记"和"清除"两个阶段:首先标记出所有需要回收的对

jdk1.7 HotSpot虚拟机 怎么查看使用的哪种垃圾收集器

问题描述 jdk1.7 HotSpot虚拟机 怎么查看使用的哪种垃圾收集器 怎么查看虚拟机使用的哪种垃圾收集器?是G1,还是CMS? 启动java的参数中没有配置-XX:+UseG1GC这种参数 $ ./java -version java version "1.7.0_45" Java(TM) SE Runtime Environment (build 1.7.0_45-b18) Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08,

垃圾收集器Serial 、Parallel、CMS、G1

这里介绍4个垃圾收集器,如果进行了错误的选择将会大大的影响程序的性能.     时至今日,仍然有两个事情困扰着开发人员:垃圾收集(GC)和了解异性(程序猿的悲鸣),后者我确实不太了解,因为我被前者搞的无暇顾及怎么了解异性,特别是当知道在JAVA8中对这一区域有了很大的改进和提升还有移除了PermGen和以一些新的令人兴奋的调优.     当我们谈到垃圾回收时,我们绝大多数都知道利用它的概念在我们日常的编程中.但是,当问题出现时,会发现很多是我们不知道的.JVM 最大误区之一就是它只有一个垃圾回收

垃圾收集器与内存分配策略

虚拟机如何判断对象是否存活? 1.引用计数算法   给对象中添加一个引用计数器,每当有一个地方引用它时,计数器就加1:当引用失效时,计数器值就减1:任何时刻计数器为0的对象就是不可能再被使用的.   考虑一种情形:对象objA和objB都有字段instance,赋值令objA.instance=objB和objB.instance=objA;除此之外,这两个对象再无任何引用,实际上这两个对象以及不可能再被访问,但是它们因为互相引用着对方,导致它们的引用计数都不为0,于是引用计数算法无法通知GC收