【基础篇】十五、JVM垃圾回收器

news2024/11/28 16:51:10

文章目录

  • 1、垃圾回收器
  • 2、Serial + Serial Old
  • 3、ParNew回收器
  • 4、CMS回收器
  • 5、Parallel Scavenge + Parallel Old
  • 6、G1垃圾回收器
  • 7、G1的回收流程:Young GC
  • 8、G1的回收流程:Mixed GC
  • 9、回收器的选择

1、垃圾回收器

对回收算法落地,出现了多种垃圾回收器:

在这里插入图片描述

搭配有:

  • G1用于年轻代和老年代
  • Serial + Serial Old
  • ParNew + CMS
  • Parallel Scavenge + Parallel Old

图中虚线为对应版本的废弃组合。

2、Serial + Serial Old

Serial:

  • 串行、单线程的年轻代垃圾回收器
  • 算法:复制算法
  • 优点:单CPU下吞吐高
  • 缺点:堆内存大时,会让用户线程长期等待,多CPU下性能差
  • 场景:单CPU,硬件配置有限

在这里插入图片描述

Serial Old:

  • Serial回收器的老年代版本
  • 依旧串行、单线程回收
  • 算法:标记整理算法

在这里插入图片描述

添加JVM参数:

-XX:+UseSerialGC 

新生代、老年代即使用Serial + Serial Old回收器组合。

3、ParNew回收器

  • 实质是对Serial在多CPU下的优化,作用于年轻代
  • 使用多线程进行垃圾回收
  • 算法:复制
  • 优点:多CPU下STW时间短
  • 缺点:回收过程相对粗暴,吞吐和STW都不如G1
  • 场景:搭配老年代的CMS

在这里插入图片描述
添加JVM参数:

-XX:+UseParNewGC

此参数对应的组合是:ParNew + Serial Old(已过时的组合)

在这里插入图片描述

4、CMS回收器

  • Concurrent Mark Sweep
  • 老年代的回收器
  • 算法:标记清除算法
  • 优点:STW时间短
  • 场景:用户请求数据量大、频率高的场景,比如订单接口、商品接口等

CMS步骤:

  • 初始标记:标记和GC Root 直接关联 的对象(不是遍历所有的引用链,因此耗时极短),此过程STW
  • 并发标记:并发标记所有对象,此过程不用暂停用户线程(不用STW)
  • 重新标记:上面并发时,有些对象的状态发生了变化,可能漏标或者错标(死了的又活了,活着的快死了),需要重标,此过程STW(但大部分对象上一步并发标记已经处理完了,漏标的占少数,所以这步STW时间短)
  • 并发清理:清理死亡对象,用户线程不用暂停(不用STW)

整个过程,有两个步骤需要STW,而这两步又耗时最短,因此,CMS的SWT短
在这里插入图片描述

CMS的缺点:

  • 内存碎片化问题:标记清除算法下产生的,CMS垃圾回收器会在Full GC后进行碎片整理,此过程STW
//调整多少次Full GC后进行整理
-XX:CMSFullGCsBeforeCompaction=N 参数(默认0
  • 浮动垃圾问题:最后一步并发清理的时候,用户线程可能又产生了垃圾,这些只能等下波了
  • 退化问题:老年代内存不足时,会退化为Serial Old
  • 线程资源争抢问题:一定的CPU核数下,并发时,CMS标记或清理线程多了,其余执行用户代码的线程就少了(CMS并发线程数可设置)

在这里插入图片描述
在这里插入图片描述

基于以上缺点,JDK14后废弃CMS。添加JVM参数:

-XX:+UseParNewGC -XX:+UseConcMarkSweepGC

新老两块的回收器搭配就是ParNew + CMS

5、Parallel Scavenge + Parallel Old

Parallel Scavenge:

  • JDK8默认的年轻代垃圾回收器
  • 多线程并行回收,关注吞吐量(用户代码执行时间/用户时间+GC时间)
  • 自动调整堆的大小
  • 算法:复制算法
  • 优点:吞吐量高且开发者可控吞吐(JVM动态调整堆的大小来满足设置的吞吐)
  • 缺点:不保证单次停顿时间(STW不保证)
  • 场景:用于大数据的处理、大文件的导出(和用户没交互,容易产生大量对象)

在这里插入图片描述

Parallel Old:

  • Parallel Scavenge的老年代版本
  • 依旧多线程
  • 算法:标记清除、整理

在这里插入图片描述

添加如下JVM参数,可以使用Parallel Scavenge + Parallel Old组合:

-XX:+UseParallelGC-XX:+UseParallelOldGC

最大暂停时间参数:

//毫秒
-XX:MaxGCPauseMillis=n

吞吐的设置:

-XX:GCTimeRatio=n
//吞吐为n,则用户线程执行时间 = n/n + 1,n=99,则99%的时间执行用户代码

开启自动调整内存大小(默认):

//JVM根据吞吐和STW最大时间自动调整堆大小
-XX:+UseAdaptiveSizePolicy

注意最大时间和吞吐两项是矛盾的,最大暂停时间极小,吞吐量又设置很大,后者可能得不到保证。添加如下JVM参数,程序启动的时候,打印所有配置项的值:

-XX:+PrintFlagsFinal

指定使用PS+PO组合,看下他们的默认配置:发现默认吞吐为99,即用户线程执行99%的时间,执行GC时间占1%,最大暂停时间则很大,相当于没有设置

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

PS:

//终端执行以下指令,打印默认参数配置项
java -XX:+PrintCommandLineFlags -version

在这里插入图片描述

6、G1垃圾回收器

关于G1:

  • G1,Garbage First,作用于年轻代+老年代
  • JDK9之后的默认垃圾回收器
  • 支持多CPU并行垃圾回收
  • 可设置最大停顿时间(最大的STW)
  • 算法:复制算法

优点:

  • 巨大的堆空间下回收也有高吞吐
  • 不会产生内存碎片

缺点:

  • JDK8之前带的G1还不够完善

G1前,堆内存的划分是连续的

在这里插入图片描述

G1下,堆被分为一块块大小相等的区Region:

  • 划分不再要求连续,比如下面两部分绿色的Eden
  • 每块面积默认 = 堆空间大小/2048
  • -XX:G1HeapRegionSize=32m可设置每块的大小,但值必须为2次幂,且在1~32之间(2、4、8、16、32)
  • 相对应的回收:年轻代回收(Young GC)、混合回收(Mixed GC)

在这里插入图片描述

使用G1需要添加JVM参数(JDK9及以后版本不用):

-XX:+UseG1GC

设置最大暂停时间:

-XX:MaxGCPauseMillis=毫秒值

7、G1的回收流程:Young GC

  • 对象新new出来依旧安置到年轻代的Eden区
  • G1判断出年轻代超过堆的max值(默认60%)时,触发Young GC
  • 标记Eden + 幸存区的存活对象
  • 根据开发者配置的最大暂停时间,选择性的将其中某一部分区域A中存活对象复制到新的幸存者区(对象头年龄+1),清空区域A

在这里插入图片描述

⚫ 这个选择一部分区域的实现思路是:G1下的Young GC,会记录回收每个区Region(Eden和幸存者区)的平均耗时,做为下次回收的依据,默认-XX:MaxGCPauseMillis=200,如果计算每块Region平均耗时为40ms,则每次触发Young GC时,就最多干掉四块

  • 后续再触发GC,就是把Eden和上次的S区存活对象复制到另一块S区
  • 某个对象年龄到达阈值(默认15),依旧放入老年代
  • 此外,对象大小超过50%的Region空间时,直接进老年代(这类特殊的老年代叫Humongous区)

在这里插入图片描述

  • 多次回收后,当堆的使用率达到阈值,触发混合回收MixedGC,用复制算法回收一轮所有年轻代、部分老年代、大对象区
//阈值默认45%,可改
-XX:InitiatingHeapOccupancyPercent默认45%

在这里插入图片描述

8、G1的回收流程:Mixed GC

  • 初始标记(initial mark)
  • 并发标记(concurrent mark)
  • 最终标记(remark或者Finalize Marking)
  • 并发清理(cleanup)
    在这里插入图片描述

注意和CMS的区别,流程像,但干的活儿不一样,且最后清理时,采用的算法也不一样。此外,G1对老年代的清理会选择存活度最低的区域来进行回收,以保证回收效率。

在这里插入图片描述

最后,因为清理是复制算法,如果清理时发现没有空Region去存放转移的对象(没地儿复制了),则转为单线程执行标记-整理算法进行Full GC,此时会导致用户线程的暂停。

在这里插入图片描述

9、回收器的选择

JDK8及之前:

  • 关注暂停时间:选ParNew + CMS
  • 关注吞吐:Parallel Scavenge + Parallel Old

JDK9及以后:

  • G1,适用较大堆并且关注暂停时间

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

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

相关文章

YOLOv5改进 | 损失函数篇 | InnerIoU、InnerSIoU、InnerWIoU、FocusIoU等损失函数

一、本文介绍 本文给大家带来的是YOLOv5最新改进,为大家带来最近新提出的InnerIoU的内容同时用Inner的思想结合SIoU、WIoU、GIoU、DIoU、EIOU、CIoU等损失函数,形成 InnerIoU、InnerSIoU、InnerWIoU等新版本损失函数,同时还结合了Focus和AIpha思想,形成的新的损失函数,其…

让充电器秒供多个快充口,乐得瑞推出1拖2功率分配快充线方案

随着PD3.1协议的市场应用越来越多,一些充电器的Type-C接口的输出功率达到百瓦及以上,如何充分利用好这类充电器设备,乐得瑞电子推出1拖2快充线缆解决方案,支持智能功率分配策略支持私有快充协议。 如上图是乐得瑞1拖2功率分配快充…

绝地求生:【违规处罚工作公示】12月25日-12月31日

12月25日至12月31日期间,共计对63,907个违规账号进行了封禁,其中53,880个账号因使用外挂被永久封禁。 若您游戏中遇到违规行为,建议您优先在游戏内进行举报; 另外您也可以在官方微信公众号【PUBG国际版】中点击“ 服务中心 - 举报…

实例:NodeJS 操作 Kafka

本人是C#出身的程序员,c#很简单就能实现,有需要的可以加我私聊。但是就目前流行的开发语言,尤其是面向web方向应用的,我感觉就是Nodejs最简单了。下面介绍: 本文将会介绍在windows环境下启动Kafka,并通过n…

《操作系统导论》笔记

操作系统三个关键:虚拟化( virtualization) 并发(concurrency) 持久性(persistence) 1 CPU虚拟化 1.1 进程 虚拟化CPU:许多任务共享物理CPU,让它们看起来像是同时运行。 时分共享:运行一个进程一段时间…

Python绘制茎叶图:plt.stem

文章目录 简介参数演示 简介 茎叶图从外观来看,更像是火柴,由基线、茎线、茎头三部分构成。最简单的示例如下 import numpy as np import matplotlib.pyplot as plt plt.stem(np.sin(np.arange(10))) plt.show()参数 stem的完整参数如下 stem([locs,…

MyBatis初学者必看:快速上手,让你的项目事半功倍!

为什么使用MyBatis 在Java程序中去连接数据库,最原始的办法是使用JDBC的API。我们先来回顾一下使用JDBC的方式,我们是如何操作数据库的。 Connection conn null; Statement stmt null; Blog blog new Blog();try {// 注册 JDBC 驱动Class.forName(&…

进阶学习——引导过程和服务控制

目录 一、引导过程 1.开机自检BIOS 2.MBR引导 3.GRUB菜单 4.加载Linux内核 5.init进程初始化 6.Centos启动过程总结 7.系统初始化进程 7.1init进程 7.2Systemd 7.2.1Systemd单元类型 7.2.2运行级别所对应的Systemd目标 二、服务控制 1.修复MBR扇区故障 1.1实验操…

前端超好玩的小游戏合集来啦--周末两天用html5做一个3D飞行兔子萝卜小游戏

文章目录 💖飞行兔子萝卜小游戏💟效果展示💟代码展示源码获取💖飞行兔子萝卜小游戏 💟效果展示 💟代码展示 <body> <script src=

欢乐钓鱼^^

欢迎来到程序小院 欢乐钓鱼 玩法&#xff1a;点击鼠标左键左右晃动的鱼钩&#xff0c;下方左右移动的鱼对准鱼的方向即可进行钓鱼&#xff0c; 不同的鱼不同的分数&#xff0c;快去钓鱼吧^^开始游戏https://www.ormcc.com/play/gameStart/241 html <div id"gamediv&qu…

力扣labuladong一刷day54天前缀树

力扣labuladong一刷day54天前缀树 文章目录 力扣labuladong一刷day54天前缀树一、208. 实现 Trie (前缀树)二、648. 单词替换三、211. 添加与搜索单词 - 数据结构设计四、1804. 实现 Trie &#xff08;前缀树&#xff09; II五、677. 键值映射 一、208. 实现 Trie (前缀树) 题…

[答疑]漏斗图,领域驱动设计叒创新了?

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 albert 2024-1-1 21:11 这篇文章说用DDD重构****&#xff0c;演示了一种漏斗图&#xff0c;请教潘老师&#xff0c;这个图是DDD提出来的吗&#xff0c;您怎么评价&#xff1f; UMLChi…

系列三十五、获取Excel中的总记录数

一、获取Excel中的总记录数 1.1、概述 使用EasyExcel开发进行文件上传时&#xff0c;通常会碰到一个问题&#xff0c;那就是Excel中的记录数太多&#xff0c;使用传统的方案进行文件上传&#xff0c;很容易就超时了&#xff0c;这时可以通过对用户上传的Excel中的数量进行限制…

优雅的通过Shell脚本生成Go的程序包

前言 随着Go语言的普及&#xff0c;越来越多的开发人员选择使用Go编写代码。虽然越来越多的公司项目已使用持续集成/持续部署&#xff08;CI/CD&#xff09;工具&#xff0c;用于自动化构建、测试和部署Go程序包&#xff0c;但存在一些部署在ECS服务器的Go程序包或需要手动编译…

编译原理Lab4-使用LightIR框架自动产生cminus-f语言的LLVM IR

[[#实验框架|实验框架]][[#实验过程|实验过程]] [[#实验过程#全局变量的设计|全局变量的设计]][[#实验过程#1ASTProgram|1ASTProgram]][[#实验过程#2ASTNum|2ASTNum]][[#实验过程#3ASTVarDeclaration|3ASTVarDeclaration]][[#实验过程#4ASTFunDeclaration|4ASTFunDeclaration]]…

概率论与数理统计 知识点+课后习题

文章目录 &#x1f496; [学习资源整合](https://www.cnblogs.com/duisheng/p/17872980.html)&#x1f4da; 总复习&#x1f4d5; 知识点⭐ 常用分布的数学期望和方差 &#x1f4d9; 选择题&#x1f4d9; 填空题&#x1f4d9; 大题1. 概率2. 概率3. 概率4. P5. 概率6. 概率密度…

读元宇宙改变一切笔记01_起源

1. 元宇宙是我们下一个生存之地 1.1. 1968年&#xff0c;只有不到10%的美国家庭拥有彩色电视&#xff0c;但当年票房排名第二位的电影《2001&#xff1a;太空漫游》&#xff08;2001: A Space Odyssey&#xff09;设想了这样的未来 1.1.1. 斯坦利库布里克(Stanley Kubrick) …

react-router-domV6.21.1版本结合ant design mobile的TabBar标签栏和Popup弹出层实现移动端路由配置

react-router-demo react-router-dom在V6版本之后更换了很多的API名称&#xff0c;在ant design mobile的TabBar配置中还是之前的旧版本&#xff0c;比如使用了switch组件等。我们在这里使用新版本的react-router-dom进行react移动端的配置 首先使用npm下载最新版的react-rout…

【前端设计】小球loading动画

欢迎来到前端设计专栏&#xff0c;本专栏收藏了一些好看且实用的前端作品&#xff0c;使用简单的html、css语法打造创意有趣的作品&#xff0c;为网站加入更多高级创意的元素。 html <!DOCTYPE html> <html lang"en"> <head><meta charset&quo…

YOLOv5改进 | 主干篇 | CSWinTransformer交叉形窗口网络改进特征融合层

一、本文介绍 本文给大家带来的改进机制是CSWin Transformer,其基于Transformer架构,创新性地引入了交叉形窗口自注意力机制,用于有效地并行处理图像的水平和垂直条带,形成交叉形窗口以提高计算效率。它还提出了局部增强位置编码(LePE),更好地处理局部位置信息,我将其…