深入理解JVM(5)——HotSpot垃圾收集器详解

HotSpot虚拟机提供了多种垃圾收集器,每种收集器都有各自的特点,没有最好的垃圾收集器,只有最适合的垃圾收集器。根据新生代和老年代各自的特点,我们应该分别为它们选择不同的收集器,以提升垃圾回收效率。

新生代垃圾收集器:

  1. Serial垃圾收集器

a)        单线程:只开启一条GC线程进行垃圾回收,并且在垃圾回收过程中停止一切用户线程,从而用户的请求或图形化界面会出现卡顿。

b)        适合客户端应用

c)        简单高效:由于Serial收集器只有一条GC线程,因此避免了线程切换的开销,从而简单高效。

d)        采用“复制”算法

  1. ParNew垃圾收集器:ParNew是Serial的多线程版本

a)        多线程并行执行:ParNew由多条GC线程并行地进行垃圾清理。但清理过程仍然需要停止一切用户线程。但由于有多条GC线程同时清理,清理速度比Serial有一定的提升。

b)        适合多CPU的服务器环境

c)        采用“复制算法”

d)        追求“降低停顿时间”:和Serial相比,ParNew使用多线程的目的就是缩短垃圾收集时间,从而减少用户线程被停顿的时间。

e)        和Serial的对比:ParNew和Serial唯一的区别就是使用了多线程进行垃圾回收,在多CPU的环境下性能比Serial会有一定程度的提升;但线程切换需要额外的开销,因此在单CPU环境中表现不如Serial。

  1. Parallel Scavenge垃圾收集器:Parallel Scavenge和ParNew一样都是多线程、新生代收集器,都使用“复制”算法进行垃圾回收。但它们有个巨大的不同点:ParNew收集器追求降低用户线程的停顿时间,因此适合交互式应用;而Parallel Scavenge追求CPU吞吐量,能够在较短的时间内完成指定任务,因此适合没有交互的后台计算。

a)        什么是吞吐量:吞吐量是指用户线程运行时间占CPU总时间的比例。CPU总时间包括:用户线程运行时间 和 GC线程运行的时间。因此,吞吐量越高表示用户线程运行时间越长,从而用户线程能够被快速处理完。

b)        降低停顿时间的两种方式

i.              在多CPU环境中使用多条GC线程,从而垃圾回收的时间减少,从而用户线程停顿的时间也减少

ii.              实现GC线程与用户线程并发执行。所谓并发,就是用户线程与GC线程交替执行,从而每次停顿的时间会减少,用户感受到的停顿感降低,但线程之间不断切换意味着需要额外的开销,从而垃圾回收和用户线程的总时间将会延长。

老年代垃圾收集器

  1. Serial Old垃圾收集器:

a)        Serial Old收集器是Serial的老年代版本

b)        单线程,在垃圾收集时只启动一条GC线程

c)        适合客户端应用

d)        它们唯一的区别就是Serial Old工作在老年代,使用“标记-整理”算法;而Serial工作在新生代,使用“复制”算法。

  1. ParNew Old垃圾收集器:Parallel Old收集器是Parallel Scavenge的老年代版本,一般它们搭配使用,追求CPU吞吐量。它们在垃圾收集时都是由多条GC线程并行执行,并停止一切用户线程。因此,由于在垃圾清理过程中没有使垃圾收集和用户线程并行执行,因此它们是追求吞吐量的垃圾收集器。
  2. CMS垃圾收集器:CMS收集器是一款追求停顿时间的老年代收集器,它在垃圾收集时使得用户线程和GC线程并行执行,因此在垃圾收集过程中用户也不会感受到明显的卡顿。但用户线程和GC线程之间不停地切换会有额外的开销,因此垃圾回收总时间就会被延长。
  3. CMS的缺点:

a)        吞吐量:由于CMS在垃圾收集过程使用用户线程和GC线程并行执行,从而线程切换会有额外开销,因此CPU吞吐量就不如在垃圾收集过程中停止一切用户线程的方式来的高。

b)        无法处理浮动垃圾,导致频繁的FullGC:由于垃圾清除过程中,用户线程和GC线程并发执行,也就是用户线程仍在执行,那么在执行过程中会产生垃圾,这些垃圾称为“浮动垃圾”。 如果CMS在垃圾清理过程中,用户线程需要在老年代中分配内存时发现空间不足时,就需要再次发起Full GC,而此时CMS正在进行清除工作,因此此时只能由Serial Old临时对老年代进行一次Full GC。

c)        使用标记-清除算法或者是标记-整理算法容易产生碎片空间

通用垃圾收集—G1垃圾收集器:目前为止最牛逼的垃圾收集器

  1. G1垃圾收集器的特点:

a)        追求停顿时间

b)        多线程GC

c)        面向服务器端使用

d)        标记-整理和复制算法合并,不会产生碎片内存

e)        可对整个堆内存进行垃圾回收

f)         可以预测停顿时间

  1. G1垃圾收集器的内存模型:G1垃圾收集器没有新生代和老年代的概念了,而是将堆划分为一块块独立的Region(区域)。当要进行垃圾收集时,首先估计每个Region中的垃圾数量,每次都从垃圾回收价值最大的Region开始回收,因此可以获得最大的回收效率。
  2. Remembered Set:一个对象和它内部所引用的对象可能不在同一个Region中,那么当垃圾回收时,每个Region都有一个Remembered Set,用于记录本区域中所有对象引用的对象所在的区域,从而在进行可达性分析时,只要在GC Roots中再加上Remembered Set即可防止对所有堆内存的遍历。

原文地址:https://www.cnblogs.com/BaoZiY/p/10632219.html

时间: 2024-08-02 03:44:46

深入理解JVM(5)——HotSpot垃圾收集器详解的相关文章

深入理解JVM实战(三)——垃圾收集策略详解

极客头条用户请点击"阅读原文",阅读排版后原文 Java虚拟机的内存模型分为五个部分,分别是:程序计数器.Java虚拟机栈.本地方法栈.堆.方法区. 这五个区域既然是存储空间,那么为了避免Java虚拟机在运行期间内存存满的情况,就必须得有一个垃圾收集者的角色,不定期地回收一些无效内存,以保障Java虚拟机能够健康地持续运行. 这个垃圾收集者就是平常我们所说的"垃圾收集器",那么垃圾收集器在何时清扫内存?清扫哪些数据?这就是接下来我们要解决的问题. 程序计数器.Jav

java - GC垃圾收集器详解(三)

以前收集器的特点 年轻代和老年代是各自独立且连续的内存块 年轻代收集必须使用单个eden+S0+S1进行复制算法 老年代收集扫描整个老年代区域 都是以尽可能少而快速地执行GC为设计原则 G1是什么 G1(Garbage-Frist)收集器,是一款面向服务端应用的收集器 从官网的描述中,我们知道G1是一种服务器端的垃圾收集器,应用在多处理器和大容量内存环境中,在提高吞吐量的同时,尽可能的满足垃圾收集暂停时间的要求.另外,它还具有以下特性: 像CMS收集器一样,能与应用程序线程并发执行 整理空闲空间

java - GC垃圾收集器详解(二)

CMS收集器 CMS收集器(ConcurrentMarkSweep:并发标记清除)是一种以获取最短回收停顿时间为目标的收集器. 适合应用在互联网站或者B/S系统的服务器上,这类应用尤其重视服务器的响应速度,希望系统停顿时间最短. CMS非常适合堆内存大.CPU核数多的服务器端应用,也是G1出现之前大型应用的首选收集器. Concurrent Mark Sweep 并发标记清除,并发收集低停顿,并发指的是与用户线程一起执行 开启该收集器的JVM参数:-XX:+UseConcMarkSreepGC,

【深入理解JVM】:HotSpot垃圾收集器

相关概念 并发和并行 这两个名词都是并发编程中的概念,在谈论垃圾收集器的上下文语境中,它们可以解释如下. 并行(Parallel):指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态. 并发(Concurrent):指用户线程与垃圾收集线程同时执行(但不一定是并行的,可能会交替执行),用户程序在继续运行,而垃圾收集程序运行于另一个CPU上. Minor GC 和 Full GC 新生代GC(Minor GC):指发生在新生代的垃圾收集动作,因为Java对象大多都具备朝生夕灭的特性,所以M

JVM的垃圾回收机制详解和调优

JVM的垃圾回收机制详解和调优 gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存.java语言并不要求jvm有gc,也没有规定gc如何工作.不过常用的jvm都有gc,而且大多数gc都使用类似的算法管理内存和执行收集操作. 1.JVM的gc概述 gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存.java语言并不要求jvm有gc,也没有规定gc如何工作.不过常用的jvm都有gc,而且大多数gc都使用类似的算法管理内存和执行收集操作. 在充分理解了垃圾收集算法和执行

python--装饰器详解

Python---装饰器详解 定义: 本质上是一个函数.作用是用来装饰另一个函数(即被装饰函数),给被装饰函数添加功能.前提是不能改变被装饰函数的源代码和调用方式.这样的一个函数称之为装饰器. 解析: 下面我们话不多说,直接用代码说明.下面是一个函数. 1 def add(): 2 b=1+2 3 print(b45 add() 程序输出: -------- 3 -------- 现在我要给这个函数增加一个解释性的句子,如下,我们可以编写一个装饰器: 1 #原函数 2 def add(): 3

C编译器、链接器、加载器详解

摘自http://blog.csdn.net/zzxian/article/details/16820035 C编译器.链接器.加载器详解 一.概述 C语言的编译链接过程要把我们编写的一个c程序(源代码)转换成可以在硬件上运行的程序(可执行代码),需要进行编译和链接.编译就是把文本形式源代码翻译为机器语言形式的目标文件的过程.链接是把目标文件.操作系统的启动代码和用到的库文件进行组织形成最终生成可加载.可执行代码的过程. 过程图解如下: 预处理器:将.c 文件转化成 .i文件,使用的gcc命令是

SpringMVC拦截器详解[附带源码分析]

目录 前言 重要接口及类介绍 源码分析 拦截器的配置 编写自定义的拦截器 总结 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:http://www.cnblogs.com/fangjian0423/p/springMVC-introduction.html 拦截器是每个Web框架必备的功能,也是个老生常谈的主题了. 本文将分析SpringMVC的拦截器功能是如何设计的,让读者了解该功能设计的原理. 重要接口及类介绍 1. Hand

spring--处理器拦截器详解——跟着开涛学SpringMVC

5.1.处理器拦截器简介 Spring Web MVC的处理器拦截器(如无特殊说明,下文所说的拦截器即处理器拦截器) 类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理.   5.1.1.常见应用场景 1.日志记录:记录请求信息的日志,以便进行信息监控.信息统计.计算PV(Page View)等. 2.权限检查:如登录检测,进入处理器检测检测是否登录,如果没有直接返回到登录页面: 3.性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时