当前位置: 首页 > news >正文

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

文章目录

    • 垃圾收集器介绍总结
    • 各个垃圾收集器之间的关系
    • 垃圾收集器使用命令及默认值
    • 详解各个垃圾收集器
      • 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,未来不会太差,只要我们不要太懒就行, 咱们下期见.
在这里插入图片描述

相关文章:

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

文章目录垃圾收集器介绍总结各个垃圾收集器之间的关系垃圾收集器使用命令及默认值详解各个垃圾收集器SerialParNewParallel ScavengeSerial OldParallel OldCMS(Concurrent Mark Sweep)G1(Garbage First)适用场景及推荐垃圾收集器介绍总结 垃圾收集器可以帮助我们进行具体的垃…...

Hive查询中的优化

目录前言优化策略推荐使用group by代替distinct去重前言 优化策略 推荐使用group by代替distinct去重 参考: hive中groupby和distinct区别以及性能比较 - cnblogs数据倾斜之count(distinct) - cnblogs 重要结论: 两者都会在map阶段count&#xff0c…...

【开发规范】go项目开发中的[流程,git,代码,目录,微服务仓库管理,静态检查]

文章目录前言一、有哪些规范我们应该遵循二、项目开发流程三、git的代码分支管理1. 分支管理2. commit规范三、go的代码规范四、go项目目录规范五、微服务该采用multi-repo还是mono-repo?1. 引言2. Repos 是什么?3. 什么是 Mono-repo?4. Mono-repo 的劣势5. 什么是…...

数组初始化方式与decimal.InvalidOperation

数组初始化方式与decimal.InvalidOperation调用函数主函数: 数组声明不同带来的报错与否1. 报错decimal.InvalidOperation的数组初始化版本2. 可行的初始化版本输出结果1. 报错时的内容2. 正常的输出计算结果原因(是否是数组与列表不同引起(?…...

【Opencv-python】之入门安装

目录 一、安装Python 1. 登录官网https://www.python.org/downloads/ 2. 任选一个版本,下载Python 3. 安装Python 记得勾选下图的Add Python 3.6 PATH, 添加python到环境变量的路径,然后选择Install now​编辑 4. 验证是否安装成功 5.退出 二、安装…...

MySQL进阶(二)

目录 1、视图 1、检查选项 2、视图的更新 3、视图作用 2、存储过程 1、语法 2、变量 1、系统变量 2、用户定义变量 3、局部变量 3、if 4、参数 5、case 6、循环 1、while 2、repeat 3、loop 7、游标、条件处理程序 8、存储函数 3、触发器 4、锁 1、全局锁 2、表级锁 …...

热爱所有热爱

想成为这样的一个人,在工作中是一名充满极客精神的Programmer,处理遇到的问题能够游刃有余,能够做出优雅的设计,写出一手优秀的代码,还有着充分的学习能力和业务能力,做一名职场中的佼佼者。 在工作之余还能…...

Redis学习之数据删除与淘汰策略(七)

这里写目录标题一、Redis数据特征二、过期数据三、过期数据删除策略3.1 数据删除策略的目标3.2 定时删除3.3 惰性删除3.4 定期删除3.5 删除策略对比3.6 实际应用四、数据淘汰策略4.1 淘汰策略概述4.2 策略配置一、Redis数据特征 Redis是一种内存级数据库,所有的数据…...

HashMap 面试专题

1、HashMap 的底层结构 ①JDK1.8 以前 JDK1.8 之前 HashMap 底层是 数组和链表 结合在一起使用也就是 链表散列。HashMap 通过 key 的hashCode 函数处理过后得到 hash 值,然后通过 (n - 1) & hash 判断当前元素存放的位置(这里的 n 指的是数组的长度…...

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

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

Java自定义生成二维码(兼容你所有的需求)

1、概述作为Java开发人员,说到生成二维码就会想到zxing开源二维码图像处理库,不可否认的是zxing确实很强大,但是实际需求中会遇到各种各样的需求是zxing满足不了的,于是就有了想法自己扩展zxing满足历史遇到的各种需求&#xff0c…...

Spring事务的隔离级别

事务隔离级别解决的是多个事务同时调⽤⼀个数据库的问题 事务传播机制解决的是⼀个事务在多个节点(⽅法)中传递的问题 事务的特性: 隔离性:多个事务在并发执行的时候,多个事务执行的一个行为模式,当一个事务执行的时候,另一个事务执行的一个行…...

JVM系统优化实践(4):以支付系统为例

您好,我是湘王,这是我的CSDN博客,欢迎您来,欢迎您再来~前面说过,JVM会将堆内存划分为年轻代、老年代两个区域。年轻代会将创建和使用完之后马上就要回收的对象放在里面,而老年代则将创建之后需要…...

16- TensorFlow实现线性回归和逻辑回归 (TensorFlow系列) (深度学习)

知识要点 线性回归要点: 生成线性数据: x np.linspace(0, 10, 20) np.random.rand(20)画点图: plt.scatter(x, y)TensorFlow定义变量: w tf.Variable(np.random.randn() * 0.02)tensor 转换为 numpy数组: b.numpy()定义优化器: optimizer tf.optimizers.SGD()定义损失: …...

无自动化测试系统设计方法论

灵活 敏捷 迭代。 自动化测试 辩思 测试必不可少 想想看没有充分测试的代码, 哪一次是一次过的? 哪一次不需要经历下测试的鞭挞? 不要以为软件代码容易改, 就对于质量不切实际的自信—那是自大! 不适用自动化测试的case 遗留系统。太多的依赖方, 不想用过多的mock > …...

架构初探-学习笔记

1 什么是架构 有关软件整体结构与组件的抽象描述,用于指导软件系统各个方面的设计。 1.1 单机架构 所有功能都实现在一个进程里,并部署在一台机器上。 1.2 单体架构 分布式部署单机架构 1.3 垂直应用架构 按应用垂直切分的单体架构 1.4 SOA架构 将…...

在成都想转行IT,选择什么专业比较好?

很多创新型的互联网服务公司的核心其实都是软件,创新的基础、运行的支撑都是软件。例如,软件应用到了出租车行业,就形成了巅覆行业的滴滴;软件应用到了金融领域,就形成互联网金融;软件运用到餐饮行业,就形成美团;软件运…...

【Spark分布式内存计算框架——Spark Streaming】4.入门案例(下)Streaming 工作原理

2.3 Streaming 工作原理 SparkStreaming处理流式数据时,按照时间间隔划分数据为微批次(Micro-Batch),每批次数据当做RDD,再进行处理分析。 以上述词频统计WordCount程序为例,讲解Streaming工作原理。 创…...

2、算法先导---思维能力与工具

题目 碎纸片的拼接复原(2013B) 内容 破碎文件的拼接在司法物证复原、历史文献修复以及军事情报获取等领域都有着重要的应用。传统上,拼接复原工作需由人工完成,准确率较高,但效率很低。特别是当碎片数量巨大,人工拼接很难在短时…...

WordPress 函数:add_theme_support() 开启主题自定义功能(全面)

add_theme_support() 用于在我们的当前使用的主题添加一些特殊的功能,函数一般写在主题的functions.php文件中,当然也可以再插件中使用钩子来调用该函数,如果是挂在钩子上,那他必须挂在after_setup_theme钩子上,因为 i…...

Winform控件开发(16)——Timer(史上最全)

前言: Timer控件的作用是按用户定义的时间间隔引发事件的计时器,说的直白点就是,他就像一个定时炸弹一样到了一定时间就爆炸一次,区别在于定时炸弹炸完了就不会再次爆炸了,但是Timer这个计时器到了下一个固定时间还会触发一次,上面那张图片就是一个典型的计时器,该定时器…...

游戏高度可配置化:通用数据引擎(data-e)及其在模块化游戏开发中的应用构想图解

游戏高度可配置化:通数据引擎在模块化游戏开发中的应用构想图解 ygluu 码客 卢益贵 目录 一、前言 二、模块化与插件 1、常规模块化 2、插件式模块化(插件开发) 三、通用数据引擎理论与构成 1、名字系统(数据类型&#xf…...

CountDownLatch与CyclicBarrier原理剖析

1.CountDownLatch 1.1 什么是CountDownLatch CountDownLatch是一个同步工具类,用来协调多个线程之间的同步,或者说起到线程之间的通信(而不是用作互斥的作用)。 CountDownLatch能够使一个线程在等待另外一些线程完成各自工作之…...

NLP中的对话机器人——预训练基准模型

引言 本文是七月在线《NLP中的对话机器人》的视频笔记,主要介绍FAQ问答型聊天机器人的实现。 场景二 上篇文章中我们解决了给定一个问题和一些回答,从中找到最佳回答的任务。 在场景二中,我们来实现: 给定新问题,从…...

C语言学习及复习笔记-【14】C文件读写

14 C文件读写 14.1打开文件 您可以使用 fopen( ) 函数来创建一个新的文件或者打开一个已有的文件,这个调用会初始化类型 FILE 的一个对象,类型 FILE包含了所有用来控制流的必要的信息。下面是这个函数调用的原型: FILE *fopen( const char…...

模拟退火算法优化灰色

clc; clear; close all; warning off; %% tic T01000; % 初始温度 Tend1e-3; % 终止温度 L200; % 各温度下的迭代次数(链长) q0.9; %降温速率 X[16.4700 96.1000 16.4700 94.4400 20.0900 92.5400 22.3900 93.3700 25.…...

Pandas怎么添加数据列删除列

Pandas怎么添加数据列 1、直接赋值 # 1、直接赋值df.loc[:, "最高气温"] df["最高气温"].str.replace("℃", "").astype("int32")df.loc[:, "最低气温"] df["最低气温"].str.replace("℃"…...

C++类和对象:构造函数和析构函数

目录 一. 类的六个默认成员函数 二. 构造函数 2.1 什么是构造函数 2.2 编译器自动生成的默认构造函数 2.3 构造函数的特性总结 三. 析构函数 3.1 什么是析构函数 3.2 编译器自动生成的析构函数 3.3 析构函数的特性总结 一. 类的六个默认成员函数 对于任意一个C类&…...

【Stata】从入门到精通.零基础小白必学的教程,一学就fei

视频教程移步:https://www.bilibili.com/video/BV1hK4y1d714/?p4&spm_id_frompageDriver&vd_sourcecc8074e9c81a225f214226065db53d32P3 第二讲 Stata处理数据全流程(上) P3 - 01:37内置数据 file example datasets使用…...

【RuoYi优化】调整JVM启动内存

📔 笔记介绍 大家好,千寻简笔记是一套全部开源的企业开发问题记录,毫无保留给个人及企业免费使用,我是作者星辰,笔记内容整理并发布,内容有误请指出,笔记源码已开源,前往Gitee搜索《chihiro-notes》,感谢您的阅读和关注。 作者各大平台直链: GitHub | Gitee | CSD…...