史上最经典垃圾回收器(CMS,G1)详解、适用场景及特点、使用命令

news2024/11/25 2:37:05

文章目录

    • 垃圾收集器介绍总结
    • 各个垃圾收集器之间的关系
    • 垃圾收集器使用命令及默认值
    • 详解各个垃圾收集器
      • Serial
      • ParNew
      • Parallel Scavenge
      • Serial Old
      • Parallel Old
      • CMS(Concurrent Mark Sweep)
      • G1(Garbage First)
    • 适用场景及推荐

垃圾收集器介绍总结

垃圾收集器可以帮助我们进行具体的垃圾回收操作,在Java中,有几款非常经典的垃圾回收器,这些经典的垃圾收集器尽管已经算不上是最先进的技术,但是它们曾在实践中千锤百炼,足够成熟,基本上可以认为是可以在生产环境中放心使用的全部垃圾收集器了.

目前主要有7款经典的垃圾回收器,笔者对这几种进行了总结,如下图所示.
可以直观的理解各个垃圾回收器的区别.

在这里插入图片描述

这里对吞吐量额外做一下说明:

吞吐量就是处理器用于 运行用户代码的时间与处理器总消耗时间 的比值.
也就是:
在这里插入图片描述
如果虚拟机完成某个任务,用户代码加上垃圾收集器总共消耗的100分钟,其中运行垃圾收集花费1分钟,那么吞吐量就是99%.

停顿时间越短就越适合与用户发生交互或需要保证响应质量的程序,比如基于浏览器的B/S系统的服务端程序,响应时间越短,用户体验越好; 而吞吐量高则可以尽快的完成程序的运算任务,可以更高效的利用处理器资源, 主要适合在后台运算而不需要太多交互的任务.

各个垃圾收集器之间的关系

各个垃圾收集器并不是可以随意搭配使用的,而是存在一定的搭配关系,如下图所示.

如果不同收集器之间的存在连线,则表示它们可以搭配使用.图中垃圾收集器所处的区域,则表示它们属于新生代垃圾收集器亦或是老年代垃圾收集器.

在这里插入图片描述

垃圾收集器使用命令及默认值

那我们怎么去使用限定使用这些垃圾收集器呢,可以使用以下命令:
在这里插入图片描述

目前大多数生产环境都使用的是jdk8, 在server模式下,默认值是UseParallelGC,也就是新生代默认是Parallel Scavenge垃圾回收器,老年代默认Serial Old垃圾收集器.

jdk9以后server模式下默认是使用G1垃圾回收器.

查看jvm使用的垃圾回收器:
命令行: java -server -XX:+PrintCommandLineFlags -version

详解各个垃圾收集器

Serial

它是最基础,历史上最悠久的收集器, 是一个新生代的单线程收集器,标记和清理都是单线程,优点是简单高效;在工作的时候必须"stop the world".

虽然它是单线程的,但并非没有用处,它仍旧是HotSpot虚拟机运行在客户端模式下的新生代默认垃圾收集器.因为在内存资源首先的环境下,它是所有收集器里消耗额外内存最小的.

同时,对于并行能力较弱的计算机来说,串行回收器的专注性和独占性往往有更好的性能表现。

ParNew

新生代收并行集器,实际上是Serial收集器的多线程版本,只是简单的将Serial并行化, 在多核CPU环境下有着比Serial更好的表现;对于其他回收策略,收集算法等等均与Serial一致.在实现上这两种收集器也共用了相当多的代码.

该收集器也是激活CMS后,新生代的默认垃圾收集器.一般和CMS进行搭配使用.

Parallel Scavenge

也是一款新生代并行收集器,同样是基于标记整理算法, 表面上和ParNew非常相似,但最大的不同点就是,Parallel Scavenge的目标在于提升吞吐量.它也是jdk8在server模式下的新生代默认收集器.

由于与吞吐量密切相关,Parallel Scavenge有一个参数还是比较重要的,-XX:+UseAdaptiveSizePolicy.这是一个开关,当这个参数被激活后,就不需要人工指定新生代,老年代大小等细节参数了,虚拟机会根据当前系统的运行情况动态调整这些参数以获得最合适的停顿时间或最大的吞吐量.这种调节方式被称为垃圾收集器的自适应调节策略.

如果你对于收集器运作不太了解,手工优化存在困难的话,使用这个自适应调节策略,把内存管理优化交给虚拟机完成也许是一个很不错的选择.只需要把最基本的设置好(如最大堆).然后使用-XX:MaxGCPauseMillis参数(更关注停顿时间)或XX:GCTimeRatio参数(更关注吞吐量)给虚拟机设计一个优化目标,具体细节的参数调优就可以交给虚拟机完成了.

-XX:MaxGCPauseMillis:最大垃圾收集暂停时间,单位为毫秒,如:-XX:MaxGCPauseMillis=200,表示垃圾收集暂停时间最大为200毫秒。默认情况下,没有指定最大垃圾收集暂停时间。如果指定了暂停时间目标,则会调整堆大小与垃圾收集相关的其他参数,使垃圾收集的暂停时间短于指定值。这些调整可能导致降低应用的整体吞吐量,也有可能无法始终满足所指定的最大垃圾收集暂停时间目标。

-XX:GCTimeRatio:吞吐量大小,如:-XX:GCTimeRatio=19,表示将垃圾收集运行时间的目标设定为应用总运行时间(用户代码运行时间+垃圾收集运行时间)的1/(1+19),即5%。默认值为99,垃圾收集的目标时间占应用总运行时间的1/(1+99),即1%.

Serial Old

Serial Old收集器是Serial的老年代版本,采用标记-整理算法,是一个单线程收集器,这个收集器的主要意义也是提供客户端模式下的HotSpot虚拟机使用.

在server模式下可能也有两种应用: 一种是与Parallel Scavenge搭配使用,一种是作为CMS收集器发生失败后的后备预案.

Parallel Old

Parallel Scavenge收集器的老年代版本;采用标记-整理算法,支持多线程并发收集.同样追求高吞吐量.

该收集器在jdk6才出来,在之前Parallel Scavenge只能与Serial Old搭配使用,但由于单线程的老年代收集中无法充分利用服务多处理器并行处理的优势,在老年代内存空间很大的情况下这种组合的吞吐量甚至不一定比ParNew+CMS组合更加优秀.

直到Parallel Old出现后,"吞吐量优先"才算有了名副其实的搭配,在注重吞吐量或者处理器资源较为稀缺的情况下都可以优先考虑Parallel Scavenge+Parallel Old组合.

CMS(Concurrent Mark Sweep)

老年代并行收集器,采用标记清除法, 追求最短回收停顿时间,具有高并发、低停顿的特点.

目前很大一部分Java应用集中在网站上或基于浏览器的B/S架构,这类应用非常关注服务的响应速度,希望停顿时间更短,CMS就非常符合这类需求.

CMS并不是独占的回收器,在CMS回收过程中,应用程序仍然在不停的工作,又会有新的垃圾不断产生,在使用CMS的过程中应该确保应用程序的内存足够可用。CMS不会等到应用程序饱和的时候才去回收垃圾,而是在某一阀值的时候开始回收,回收阀值可用指定的参数进行配置,-XX:CMSInitiatingOccupancyFraction来指定,默认为68,也就是说当老年代的空间使用率达到68%的时候,会执行CMS回收。如果内存使用率增长的很快,在CMS执行的过程中,已经出现了内存不足的情况,此时CMS回收就会失败,虚拟机将启动老年代串行回收器进行垃圾回收,这会导致应用程序中断,直到垃圾回收完成后才会正常工作,这个过程GC的停顿时间可能较长,所以-XX:CMSInitiatingOccupancyFraction的设置要根据实际的情况.

CMS是HotSpot追求低停顿的第一次成功尝试,有自己的优点,但还是有一些缺点:

  1. 在处理器核心数量不足4个时,CMS对应用程序的影响可能变得很大,可能导致用户程序速度忽然大幅降低,因为其会占用一部分处理器资源.

  2. 当内存回收使用增长过快时,CMS回收失败时,就会Full GC,启用老年代串行回收器进行回收

  3. 其采用标记清除法,会产生空间碎片的问题,处理这些碎片又会花费较多时间

G1(Garbage First)

G1收集器是垃圾收集器技术发展史上里程碑式的成果.目前已经是jdk9及以上版本的server模式下的默认垃圾收集器了.

之前的收集器要么工作在新生代,要么工作在老年代,而G1跳出了这个樊笼,它可以面向堆内任何部分进行回收,衡量标准不再是它属于哪个分代,而是哪块内存中存放的垃圾数量更多,回收受益最大,这就是G1收集器的Mixed GC模式.

G1作为CMS未来的继承人,追求低延迟,但并非纯粹的追求低延迟,官方给其设定的目标是在延迟可控的情况下获得尽可能高的吞吐量.所以担当起了"全功能收集器"的重任与期望.

G1把连续的Java堆分成多个大小相等的独立区域(Region),每一个Region都可以根据需要,扮演新生代的Eden空间,survivo空间,亦或是老年代空间,收集器能够对扮演不同角色的region采用不同的策略去进行回收,这样无论是刚创建的对象,还是已经存活了一段时间的对象等都能获得很好的收集结果.

G1相比CMS有很多的优点,比如说不会产生空间碎片、回收之后能够提供规整的可用内存、更不容易产生Full GC等等.但G1对对于CMS的碾压并不是全方位的,例如:G1为了垃圾回收而使用的内存和运行时的额外负载都比CMS要高.

适用场景及推荐

以上七款经典的垃圾回收器,并没有绝对的好坏之分,更不存在"万能"的垃圾收集器.所以我们只能根据具体应用,具体环境去选择最适合的一个垃圾收集器.

首先要明确一个观点,如果默认的收集器没有达到预期的性能,那么首先尝试调整堆和代的大小以满足预期的目标。如果性能仍然不够,再尝试不同的收集器:使用并发收集器来减少暂停时间,并使用并行收集器来提高多处理器硬件上的总体吞吐量。

  1. 如果应用程序就是一个小内存(最多大约100 MB),建议使用选项-XX:+UseSerialGC选择串行收集器。
  2. 如果应用程序将在单个处理器上运行,并且没有暂停时间要求,那么使用选项-XX:+UseSerialGC选择串行收集器。
  3. 如果应用程序性能、吞吐量是第一优先级,并且没有暂停时间要求,一秒钟或更长时间的暂停都是可以接受的,那么建议使用-XX:+UseParallelGC或-XX:+UseParallelOldGC 选择并行收集器。纯后台程序无交互,并且是多处理器的,推荐考虑-XX:+UseParallelOldGC
  4. 如果响应时间比总体吞吐量更重要,比如说与用户进行交互的,垃圾收集暂停必须很短,那么可以CMS或G1作为垃圾收集器,-XX:+UseG1GC或-XX:+UseConcMarkSweepGC
    目前在小内存的应用上,CMS的表现大概率仍会优于G1,而在大内存应用上,G1则大多能发挥其优势,这个优劣势的堆容量平衡点在6-8G之间.

今天的分享就到这里了,有问题可以在评论区留言,均会及时回复呀.
我是bling,未来不会太差,只要我们不要太懒就行, 咱们下期见.
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/373723.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HDFS优化

单节点多块磁盘数据均衡 生成HDFS块均衡计划 hdfs diskbalancer -plan node1 执行均衡计划,node1.plan.json均衡计划文件 hdfs diskbalancer -execute node1.plan.json 查看当前均衡任务的执行情况 hdfs diskbalancer -query node1 取消均衡任务hdfs diskbalancer -cancel nod…

(三十九)undo log版本链是个什么东西?

今天我们正式开始切入讲解MySQL中多个事务并发执行时的隔离到底是怎么做的,因为我们知道默认是骚气的RR隔离级别,也就是说脏写、脏读、不可重复读、幻读,都不会发生,每个事务执行的时候,跟别的事务压根儿就没关系&…

移动web基础

初始缩小&#xff1a;布局视口大于视觉视口 初始放大&#xff1a;布局视口小于视觉视口 布局视口等于视觉视口&#xff08;这种动作行为叫做理想视口&#xff09; <meta name"viewport" content"width375" /> <meta name"viewport"…

云原生|kubernetes|网络插件flannel二进制部署和calico的yaml清单部署总结版

前言&#xff1a; 前面写了一些关于calico的文章&#xff0c;但感觉好像是浅尝辄止&#xff0c;分散在了几篇文章内&#xff0c;并且很多地方还是没有说的太清楚云原生|kubernetes|kubernetes的网络插件calico和flannel安装以及切换_calico换flannel_晚风_END的博客-CSDN博客 …

在C#中使用信号量解决多线程访问共享资源的冲突问题

目前在我写的233篇原创文章中&#xff0c;有两篇是粉丝可见的&#xff0c;其中《C#线程的参数传递、获取线程返回值以及处理多线程冲突》这篇文章有179个粉丝关注&#xff0c;看到不断有人关注这篇文章&#xff0c;这表明学习C#的人还是挺多的&#xff0c;感觉文章内容不够厚实…

泛型<E>

泛型 案例引出泛型 按要求写出代码&#xff1a; 在ArrayList中添加3个Dog对象&#xff0c;Dog对象有name和age两个属性&#xff0c;且输出name和age public class test1 {public static void main(String[] args) {ArrayList list new ArrayList();list.add(new Dog(10,&quo…

Python解题 - CSDN周赛第32期 - 运输石油(三维背包)

上期周赛因为最后一题出现bug&#xff0c;再加上都是经典的模板题&#xff0c;问哥就懒得写题解了。 本期也是有两道考过的题目&#xff0c;不过最后一题因为考到了背包问题的特殊类型&#xff0c;还是值得拿出来记个笔记。 第一题&#xff1a;传奇霸业 传奇霸业&#xff0c;是…

Unity高程图生成

序大概就是根据一个灰度图&#xff0c;生成一个地形。分两步来实现吧&#xff1b;首先&#xff0c;用随机数生成地形&#xff1b;然后&#xff0c;根据灰度图生成地形。小白&#xff0c;没啥基础&#xff0c;所以只能慢慢来。参考&#xff1a;【萌新图形学】地形网格生成入门 含…

基于stm32电梯管理系统设计

基于stm32电梯管理系统设计这里记录一下以前自己做的嵌入式课程设计&#xff0c;报告中的图片和文字太多了&#xff0c;全部一个一个把搬过来太麻烦了,需要完整文本和代码自行q我963160156&#xff0c;也可在微信公众号 *高级嵌入式软件* 里回复 *电梯* 查看完整版文章摘要关键…

Oracle Apex 21.2 安装过程

什么是 Oracle APEX&#xff1f; Oracle APEX 是广受欢迎的企业级低代码应用平台。借助该平台&#xff0c;您可以构建功能先进的可扩展安全企业应用&#xff0c;并在任何位置&#xff08;云或内部部署&#xff09;部署这些应用。 使用 APEX&#xff0c;开发人员可快速开发并部…

域组策略自动更新实验报告

域组策略自动更新实验报告 域组策略自动更新实验报告 作者: 高兴源 1要求、我公司为了完善员工的安全性和系统正常漏洞的维护&#xff0c;所以采用域组策略自动更新的方法来提高账户安全性&#xff0c;减少了用户的错误。 1.实验环境如下1台2008r2一台创建域&#xff0c;一台wi…

【云原生】k8s中Pod进阶资源限制与探针

一、Pod 进阶 1、资源限制 当定义 Pod 时可以选择性地为每个容器设定所需要的资源数量。 最常见的可设定资源是 CPU 和内存大小&#xff0c;以及其他类型的资源。 当为 Pod 中的容器指定了 request 资源时&#xff0c;调度器就使用该信息来决定将 Pod 调度到哪个节点上。当还…

嵌入式 STM32 步进电机驱动,干货满满,建议收藏

目录 步进电机 1、步进电机驱动原理 2、步进电机驱动 3、步进电机应用 1、第一步&#xff1a;初始化IO口 2、设置行进方式 四、源码 步进电机 步进电机被广泛应用于ATM机、喷绘机、刻字机、写真机、喷涂设备、医疗仪器及设备、计算机外设及海量存储设备、精密仪器、工业…

_improve-3

createElement过程 React.createElement()&#xff1a; 根据指定的第一个参数创建一个React元素 React.createElement(type,[props],[...children] )第一个参数是必填&#xff0c;传入的是似HTML标签名称&#xff0c;eg: ul, li第二个参数是选填&#xff0c;表示的是属性&#…

String、StringBuffer和StringBuilder的详解

目录 一、String讲解 1.String&#xff08;String字符串常量&#xff09; 2.String 拼接方式与性能的影响 二、StringBuffer 和 StringBuilder 讲解 1.StringBuffer 和 StringBuilder 使用场景:(StringBuffer、StringBuilder字符串变量) 2.StringBuffer的使用 3.StringB…

shell脚本常用命令

shell概述 shell是一个命令行解释器&#xff0c;它接收应用程序/用户命令&#xff0c;然后调用操作系统内核。 shell还是一个功能强大的编程语言&#xff0c;易编写、易调试、灵活性强。 shell解析器 查看系统自带的所有shell解析器 cat /etc/shells查看系统默认的shell解析…

超算中心、并行计算

现在超算中心已经迅速发展 合肥&#xff1a; 合肥先进中心 合肥曙光超算中心平台 合肥安徽大学超算中心 合肥中科大超算中心 合肥中科院超算中心 合肥大一点的公司都会有自己的集群&#xff0c; 超算中心又称为集群&#xff0c;一般集群是小型服务器组成&#xff0c;超…

EasyRecovery16免费的电脑的数据恢复工具

常见的数据恢复有两种方式&#xff0c;第一种方式是找别人恢复&#xff0c;按照市场价来说&#xff0c;数据恢复的价格每次在100-500之间&#xff0c;但这种方式容易使自己设备上的隐私资料泄露出去&#xff0c;不安全。 另一种方式则是自己学会数据恢复的方法&#xff0c;有问…

逻辑回归

逻辑回归 在分类问题中&#xff0c;要预测的变量y为离散值&#xff08;y0~1&#xff09;&#xff0c;逻辑回归模型的输出变量范围始终在 0 和 1 之间。 训练集为 {(x(1),y(1)),(x(2),y(2)),...,(x(m),y(m))}\{(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),...,(x^{(m)},y^{(m)})\} {…

地址,指针,指针变量是什么?他们的区别?符号(*)在不同位置的解释?

指针是C语言中的一个重要概念&#xff0c;也是C语言的一个重要特色&#xff1b;使用指针&#xff0c;可以使程序简洁、紧凑、高效。不掌握指针&#xff0c;就没有掌握C语言的精华。 目录 一、定义 1.1地址 1.2指针 1.3指针变量 1.4指针和指针变量的区别 二、使用指针变量…