链接: JVM垃圾收集—垃圾收集算法

上一篇介绍了垃圾收集算法及分区,这篇我们来学习垃圾收集器

文章目录

  • Serial
  • ParNew
  • Parallel Scavenge
  • Serial Old
  • Parallel Old
  • CMS (Concurrent Mark Sweep)
  • G1
  • 理解吞吐量和停顿时间
  • 如何选择合适的垃圾收集器呢


首先我们要知道垃圾收集器有三种类型:

串行收集器 Serial 和 Serial Old
只能有一个垃圾回收线程执行,用户线程暂停。(适用于内存较小的嵌入式设备)

并行收集器[吞吐量优先] Paraller Scanvenge、Parallel Old
多条垃圾收集线程并行工作,但此时用户线程仍然处于等待阶段。(适用于科学计算、后台处理等若干交互场景)

并发收集器[停顿时间优先] CMS、G1
用户线程和垃圾收集线程同时执行(但并不一定是并行的,可能是交替执行的),垃圾收集线程在执行的时候不会停顿用户线程的运行。(适用于相对时间有要求的场景,比如WEB)

我按照发展顺序给大家介绍一下:

Serial

  • 复制算法
  • 新生代
  • 单线程收集器

特点:它只会使用一个CPU或者一条收集线程去完成垃圾收集工作,更重要的是其在垃圾收集的时候需要暂停其他线程。

优点:简单高效

缺点:收集过程需要暂停所有线程。

应用:Client模式下的默认新生代收集器(Serial收集器是最基本、发展历史最悠久的收集,之前(JDK1.3.1之前)是虚拟机新生代收集器的唯一选择。)

ParNew

  • 复制算法
  • 新生代
  • 多线程收集器

特点:ParNew收集器实质上是Serial收集器的多线程并行版本,除了同时使用多条线程进行垃圾收集之外,其余的行为包括Serial收集器可用的所有控制参数(例如:-XX:SurvivorRatio、-XX: PretenureSizeThreshold、-XX:HandlePromotionFailure等)、收集算法、Stop The World、对象分配规 则、回收策略等都与Serial收集器完全一致,在实现上这两种收集器也共用了相当多的代码。

优点:多CPU时,比Serial效率更高。

缺点:收集过程暂停所有的应用程序,单CPU核心时比Serial效率差。

应用:运行在Server模式下的虚拟机中首选的新生代收集器。

Parallel Scavenge

此收集器与吞吐量关系密切,故也称为吞吐量优先收集器。

  • 复制算法
  • 新生代
  • 多线程收集器
  • 关注吞吐量

特点:多线程

Parallel Scavenge收集器使用两个参数控制吞吐量:
控制最大的垃圾收集停顿时间 XX:MaxGCPauseMillis
直接设置吞吐量的大小 XX:GCTimeRatio

吞吐量 = 运行用户代码时间 / 运行用户代码时间 + 运行垃圾收集时间。
如果虚拟机完成某个任务,用户代码加上垃圾收集器总共耗时100分钟,其中垃圾收集器花费了1分钟,那吞吐量就是 99 / 100= 99%。
吞吐量越大,意味着垃圾收集的时间更短、则用户代码可以充分利用CPU资源,尽快完成程序的运算任务。

这里不是你设置了就一定有效,虚拟机会尽可能的靠近你设置的数值,并不是绝对一致

Serial Old

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

  • 标记整理
  • 老年代
  • 单线程收集器

Parallel Old

  • 标记整理
  • 老年代
  • 多线程收集器
  • 关注吞吐量


特点:多线程,采用标记-整理算法。

应用场景:注重高吞吐量以及CPU资源敏感的场合

CMS (Concurrent Mark Sweep)

是一种以获取最短回收停顿时间为目标的收集器

  • 标记清除
  • 老年代
  • 并发收集器
  • 关注最短停顿时间

应用场景:适用于注重服务的响应速度,希望系统停顿时间最短,给用户带来良好的体验。比如web服务,b/s结构。

工作分为四步:
第一步、初始标记(STW),标记GC Roots能直接关联到的对象,速度非常快。

第二步、并发标记,进行GC Roots Tracing ,就是从GC Roots开始找到它能引用的所有对象的过程。

第三步、重新标记(STW),为了修成并发标记期间因用户程序继续运作导致标记产生变动的一部分对象的标记记录。这个阶段的停顿时间一般会比初始标记阶段稍长一些,但远比并发标记的时间要短。

第四步、并发清除,在整个过程中耗时最长的并发标记和并发清除过程,收集器线程都可以与用户线程一起工作,因此,从总体上看,CMS收集器的内存回收过程与用户线程一起并发执行的


优点:并发收集、并发清除、低停顿。

缺点:对CPU要求高,无法处理浮动垃圾、产生大量空间碎片、并发阶段会降低吞吐量。

  1. 对CPU敏感,并发阶段虽然不会导致用户线程暂停,但是它总是要线程执行,还是会占用CPU资源,(一定程度上也是,吞吐量的下降)
  2. 无法处理浮动垃圾:在最后一步并发清理过程中,用户线程执行也会产生垃圾,但是这部分垃圾是在标记之后,所以只有等到下一次 gc 的时候清理掉。
  3. 产生大量空间碎片、并发阶段会降低吞吐量。

这里有一个刁钻的面试问题:
CMS默认晋升老年代为6的原因: 简单来说,CMS对内存尤其敏感,且会导致单线程Serial FullGC 这个是非常严重的后果,而从结果上说越大的MaxTenuringThreshold会更快的导致heap的碎片化(不光old 区,首先要明白对于内存的分配并不是真的一个对象一个对象紧密排列的),所以历代CMS 默认这个值都会比较小(JDK8以前是4,之后调整为6)

G1

  • 分代收集(仍然保留分代的概念)
  • 并行与并发
  • 老年代和新生代
  • 关注最短停顿时间
  • 内存分为Region[ˈriːdʒən] 区(内存是否连续)
  • 可以设置最短停顿时间

工作也是分为四步:
第一步、初始标记(STW),标记GC Roots能直接关联到的对象(速度很快)。

第二步、并发标记,进行 GC Roots Tracing,就是从GC Roots开始找到它能引用的所有其他对象的过程。

第三步、最终标记(STW),为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分的标记记录。这个阶段的停顿时间一般会比初始标记阶段稍微长,但是要比并发标记要短。

第四步、筛选回收(STW),对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间指定回收计划。


G1 总结:
JDK 7 开始使用,JDK8非常成熟,JDK9默认的垃圾收集器。

如果停顿时间过短,会造成频繁垃圾回收,会导致OOM:GC overhead limitexceeded (超过98%的时间用来做GC并且回收了不到2%的堆内存时会抛出此异常)

虚拟机怎么判断是否需要使用G1收集器?
答:50%以上的堆被存活对象占用、对象分配和晋升的速度变化非常大、垃圾回收时间较长。

理解吞吐量和停顿时间

停顿时间 = 垃圾收集器进行垃圾回收的执行时间
吞吐量 = 运行用户代码时间 / 运行用户代码时间 + 运行垃圾收集时间。

如果虚拟机完成某个任务,用户代码加上垃圾收集器总共耗时100分钟,其中垃圾收集器花费了1分钟,那吞吐量就是 99 / 100= 99%。
吞吐量越大,意味着垃圾收集的时间更短、则用户代码可以充分利用CPU资源,尽快完成程序的运算任务。

停顿时间越短就越适合需要和用户交互的程序,良好的响应速度能提升用户体验; 高吞吐量则可以高效地利用CPU时间,尽快完成程序的运算任务,主要适合在后台运算而不 需要太多交互的任务。

吞吐量和停顿时间是衡量垃圾回收器的标准,我们进行调优也是观察这两个变量。

如何选择合适的垃圾收集器呢

这个准则只能参考,因为性能取决于堆的大小,应用程序维护的实时数据量以及可用处理器的数量和速度

大白话:牛逼哄哄的硬件设备不怎么需要调优,垃圾设备才考验你的调优技能。

如果应用程序的内存在100M左右,使用串行收集器 -XX:+UseSerialGC。

如果是单核心,并且没有停顿要求,默认收集器,或者选择带有选项的-XX:+UseSerialGC

如果允许停顿时间超过1秒或者更长时间,默认收集器,或者选择并行-XX:+UseParallelGC

如果响应时间最重要,并且不能超过1秒,使用并发收集器 -XX:+UseConcMarkSweepGC or -XX:+UseG1GC

1.8默认的垃圾回收:PS + ParallelOld

  • -XX:+UseSerialGC = Serial New (DefNew) + Serial Old
    小型程序。默认情况下不会是这种选项,HotSpot会根据计算及配置和JDK版本自动选择收集器
  • -XX:+UseParNewGC = ParNew + SerialOld
    这个组合已经很少用(在某些版本中已经废弃)
    为什么废弃的官方解释:
    链接: Why Remove support for ParNew+SerialOld and DefNew+CMS in the future?
  • -XX:+UseConc(urrent)MarkSweepGC = ParNew + CMS + Serial Old
  • -XX:+UseParallelGC = Parallel Scavenge + Parallel Old (1.8默认) 【PS +SerialOld】
  • -XX:+UseParallelOldGC = Parallel Scavenge + Parallel Old
  • XX:+UseG1GC = G1

JVM垃圾收集—垃圾收集器及常见组合参数相关推荐

  1. JVM常用垃圾收集器

    前言 在上一篇,我们谈到了JVM中的常用垃圾回收算法,并了解了JVM中针对堆区中不同的分代采用不同的垃圾回收算法 在了解了垃圾回收算法之后,很多伙伴不禁在想,既然是分代垃圾回收,自然新生代和老年代的垃 ...

  2. JVM(四)--垃圾收集器

    JVM(四)–垃圾收集器 这篇博客的内容包括: 一.垃圾收集器: 1,Serial 收集器: 2,ParNew 收集器: 3, Parallel Scavenge 收集器: 4,Serial Old收 ...

  3. JVM之垃圾收集算法和垃圾收集器详解

    这篇文章相比上一篇记录性的,多了不少我自己的理解,花费了很大的功夫整理,如果有时间和精力建议好好看一看深入理解JVM这本书. 也建议熟读背诵. JVM-垃圾收集器和内存分配策略 程序计数器.虚拟机栈. ...

  4. JVM之垃圾收集器回收种类

    JVM之垃圾收集器回收种类 目录 面试常见问题 串行并行并发G1四大垃圾回收方式 如何查看默认的垃圾收集器 JVM默认的垃圾收集器有哪些 GC之7大垃圾收集器详解 1. 面试常见问题 GC垃圾回收算法 ...

  5. jvm默认垃圾收集器

    jdk1.7 默认垃圾收集器Parallel Scavenge(新生代)+Parallel Old(老年代) jdk1.8 默认垃圾收集器Parallel Scavenge(新生代)+Parallel ...

  6. 深入理解JVM - ZGC垃圾收集器

    如果下面的一些概念有些不清楚的可以先看深入理解JVM - 垃圾收集器和深入理解JVM - Shenandoah垃圾收集器. ZGC(Z Garbage Collector)是一款由Oracle公司研发 ...

  7. 初探JVM之垃圾收集器

    前面大约了解了下JVM的垃圾收集算法,如果说收集算法是内存回收的方法,那么垃圾收集器就是内存回收的具体实现.现在HotSpot虚拟机都是用的G1收集器. 这里先总结下具体收集器的使用地方: 新生代:S ...

  8. JVM(三)--垃圾收集算法

    JVM(三)–垃圾收集算法 这篇博客的内容包括: 一.垃圾收集算法: 1,标记--清除算法: 2,复制算法: 3,标记--整理算法: 4,分代收集算法: 二.涉及到的问题: 1,标记清除,标记整理,复 ...

  9. JVM中垃圾收集算法总结

      通过前面的介绍我们了解了对象创建和销毁的过程.那么JVM中垃圾收集器具体对对象回收采用的是什么算法呢?本文主要记录下JVM中垃圾收集的几种算法. 文章目录 JVM的垃圾回收的算法 标记-清除算法( ...

最新文章

  1. healpy的安装(包括healpix)
  2. Notice of the completion of the blog migration
  3. excel通过js导入到页面_基于Excel和Java自动化工作流程:发票生成器示例
  4. “千年虫”,计算机的巨大BUG!
  5. firebase使用_如何开始使用Firebase Hosting
  6. easymock_EasyMock注释– JUnit 4
  7. 用于转化的XML样式表语言
  8. 使用new和delete
  9. devops之 --- git可视化工具sourcetree
  10. 一分钟学习静态网页制作
  11. 关于Windows 8 用户使用习惯调查结果
  12. cesium实现立体墙(垂直、水平)渐变泛光效果
  13. python简单应用!用爬虫来采集天猫所有优惠券信息,写入本地文件
  14. Matlab基本函数-ceil函数
  15. 春风十里,不如见到你
  16. 零基础编程教学实录-000 思考要与不要
  17. 日本国家旅游局的新版《日本本土风情导览》主打人迹罕至的名胜、劲酷的景点以及鲜为人知的攻略
  18. linux中more是什么命令,linux系统more命令
  19. 浅谈通用的字典表结构设计
  20. matlab怎么对语音信号取样,语音信号采样和频谱分析

热门文章

  1. b树的表示形式_B.Com的完整形式是什么?
  2. 清华大学出版社与SAP签署战略合作协议
  3. C++ 基础概念(二)
  4. win10 kms激活
  5. 手机上的浏览器有几种内核
  6. 如何高效利用GitHub
  7. linux卸载mate,【重大更新】最完美的ADB一键卸载工具,新增卸载后悔重装功能,小白福利哈!基于160...
  8. 如何用Zabbix监控OpenWrt路由器-Zabbix-Agent安装篇
  9. c语言统计输入文本不同字母单词数,统计文本中单词的个数
  10. 浅谈DevSecOps工具链中的源代码安全保障