JVM六种常见的垃圾回收器-重点含CMS过程详解

news2024/11/15 21:41:34

一、jdk 1.8 及其之前的分代模型: 

 堆内存结构必须熟悉:(垃圾回收,性能调优常用)

过程简单分析:

①年轻代和老年代在堆内存中的占比默认 1 :2
②年轻代又分为两个区,伊甸园区(Eden)和幸存区(S0和S1),分别占8:1:1
③新对象会先放到伊甸园区,当伊甸园区被对象占满时,会有执行引擎开启一个GC垃圾收集线程(利用根可达性分析算法判断是否是非垃圾对象),没有被引用的对象就是需要被回收的,然后非垃圾对象就会被移动到幸存区S0,并且寿命+1(说明经历了一次垃圾回收)。
继续重复刚刚,新对象又会放到伊甸园区,当伊甸园区再次被对象占满时,又会有执行引擎开启一 个GC垃圾收集线程,将 非垃圾对象移动到S1,同时 年龄+1,S0中的对象,如果是垃圾对象会直接被 回收,若不是垃圾对象,会被放到S1,寿命再+1,(移动用到的是标记复制算法)。
④当寿命到达15时,(经历了15次Minor GC),就将该对象移动到老年代中去。
⑤当老年代也被堆满时,就会产生老年代 GC,即Full GC。(老年代满了清理时,大部分垃圾回收器用到的是标记整理算法)。

二、常见的垃圾回收器:

(左边分代模型,用于jdk1.8及之前; 右边的分区模型,1.9及之后)

(1)串行垃圾回收器(Serial  +  SerialOld): 
        单线程的工作方式(会暂停所有用户线程)

 (2)并行的垃圾回收器[高吞吐量](Parallel Scavenge + Paraller Old) 并行的垃圾回收器[PS+PO---jdk 8默认的垃圾回收器]

 综上四种垃圾回收器 Serial SerialOld PS PO都会导致一个现象: 用户线程的阻塞!
        用户线程暂停 <==>  STW 
    比如:垃圾收集的时候,用户在访问的时候会直接卡主...没有线程来给用户来用.

 ☆☆☆(3)并发的垃圾回收器[高响应速度] ParNew(新生代) + CMS(老年代)  ☆☆☆ 

   CMS:Concurrent Mark Sweep并发标记清除
   ParNew是在Parallel Scavenge基础上做的改良,配合CMS使用,但大致没什么变化!

 

 别的老年代的Serial Old和PO都采取"标记整理",但是CMS采取"标记清除"!!

 (1) 初始标记: 
        找到所有GC Root根对象,短暂STW.简单标记一下
(2) 并发标记: 
        - 根据GC Roots的直接关联对象开始进行对象图的遍历.且该阶段不会暂停用户线程,允许gc线程和用户线程并发执行
        - 通过写屏障技术记录下发生错标问题的黑色对象..并放入队列中
(3) 重新标记:
        会通过"增量更新"的解决方案解决上一阶段产生的错标问题.
(4) 并发清理:
        清理掉确定会被回收的垃圾

  • 浮动垃圾:

    在gc线程与用户线程并发进行的阶段,gc线程在"并发标记"阶段,在搜集垃圾,但是在此时阶        段用户线程的操作导致的原先通过"初始标记"的"非垃圾对象"变为"垃圾对象",而此时gc收集

    器无法检测到,则该垃圾对象被称为"浮动垃圾".

  • 错标:

    在"初始标记"的垃圾对象,在"并发标记"阶段因为用户线程的影响变为了非垃圾对象.
    此时称为错标!

注意:
    (1)浮动垃圾无所谓,在下次垃圾回收的时候会把该垃圾回收.不会有什么特别的影响.
       但是"错标"的线程,会导致要使用的对象被回收了.就会造成影响.
    所以接下来的"重新标记"阶段就是解决"错标"的问题!!!
    (2)"初始标记"和"重新标记"都会产生极其短暂的STW.但可忽略不计!
    (3)当CMS并发处理失败的时候,会立马切换Serial Old来清理!(替补!!)
    (4) CMS解决错标问题采用了"增量更新"的方式.对于那些黑色增加对白色的引用,会通过写屏障的
        技术记录下来,再重新标记阶段进行以黑色为根重新扫描一遍,来解决错标的问题!

CMS缺点,不好的地方:
    (1)内存碎片
    (2)浮动垃圾
    (3)如果CMS运行期间预留的空间不足以让用户线程分配一个对象,则并发失败.
        并发失败时会先冻结用户线程,然后启动Serial Old来收集老年代.

 总结:
    (1)CMS解决了什么样的问题??
        - 解决了STW时间过长的问题,使垃圾回收时用户的等待时间变短
    
    (2)jdk 1.8之前都是分代垃圾回收,所以就是这么分代垃圾回收器.
        jdk 1.8之后都是分区垃圾回收.所以G1 ZGC等就没有老年代 新生代这种概念了!

 三、CMS并发失败的问题?

在第四阶段并发清理阶段CMS不会STW,依旧gc线程和用户线程一起运行.并不能像别的老年代垃圾回收器那样等待垃圾快满了再回收, 而是在并发清理阶段预留一定的空间给程序运行.当无法为程序分配足够的空间时,则并发失败,冻结用户线程,然后换为Serial Old来清理.

别的垃圾回收器: 我gc线程垃圾回收之后你用户线程再使用,

而CMS就是在并发清理(回收阶段)也会让你用户线程继续跑.所以CMS就需要在垃圾回收阶段预留给用户线程足够的空间来使用,一旦用户线程要使用的空间大于预留的空间,则并发失败!
 

 四、CMS最严重的两个问题?以及优化??

- 标记清除造成的内存碎片问题

晋升失败时候,新生代发生Minnor GC,幸存区中放不下要存活的对象,只能触发对象担保机制,
晋升老年代,由于内存碎片过多,导致大对象没法被放下!

解决: 让CMS进行一定次数的Full GC的后进行一次标记整理的算法,控制住内存碎片的数量.
       可以通过参数配置...        

- 并发失败时的Serial Old

解决: 降低触发CMS GC的阈值...让其预留够足够的空间!
 

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

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

相关文章

给Ollama套个WebUI,方便使用

Ollama 基本的安装使用参考前文 https://xugaoxiang.com/2024/05/01/ollama-offline-deploy/&#xff0c;前文使用的模型是 llama2&#xff0c;本篇将使用 llama3&#xff0c;因此在启动时&#xff0c;命令是 ollama run llama3。 Ollama Llama3 Llama3 是 Meta 发布的大语言模…

双向链表的简单实现

目录 1. 双向链表的结构 2.双向链表的实现 2.1 初始化 2.2 增 2.2.1 尾插 ​编辑 2.2.2 头插 3.删 2.3.1 尾删 2.3.2 头删 4. 找 5.任意位置插入 5.1 任意位置前插入 ​编辑 5.2 任意位置后插入 ​编辑 6. 任意位置删除 ​编辑 7. 改 8. 链表的销毁 3. 顺序…

基于JSP的酒店客房管理系统(二)

目录 第二章 相关技术介绍 2.1 Jsp的简介 2.2 sql server 2005 的简介 第三章 系统的分析与设计 3.1 系统需求分析 1&#xff0e;理解需求 2&#xff0e;需求分析 3.2开发及运行环境 3.3功能模块的设计 3.3.1 设计目标 3.3.2 客房管理系统前台的设计 3.3.3 操作员管…

牛角源码 | 【高级版】威客点赞悬赏任务源码/赚钱系统抖音快手火山悬赏任务站

点赞任务平台 无BUG完美自营版&#xff01; 霸屏天下赚钱系统源码/抖音快手火山悬赏任务平台 全新ui界面修复升级版任务系统&#xff0c;非市场垃圾版本。非常适合运营&#xff01; 下载地址&#xff1a;【高级版】威客点赞悬赏任务源码/赚钱系统抖音快手火山悬赏任务站 - 牛…

深入解析I2C协议:通讯简化之道

在现代电子系统中&#xff0c;组件间的通信是必不可少的。而I2C协议&#xff08;Inter-Integrated Circuit&#xff09;&#xff0c;由Philips Semiconductor&#xff08;现为NXP Semiconductors&#xff09;在1980s初期发明&#xff0c;已成为一种广泛使用的串行通信协议。其设…

cocos=》 预乘、混合(黑边、白色)

简介 预乘&#xff0c;指的是在数据提交给GPU之前&#xff0c;就对纹理的RGB分量与alpha值进行计算。 预乘计算 结果颜色 源颜色值 目标颜色值 * (1 - 源 alpha 值) result source.RGB dest.RGB * (1 - source.A); 对应的颜色混合函数设置为 gl.blendFunc(gl.ONE, gl.…

【动态规划】投资问题

本文利用markdown基于https://blog.csdn.net/qq_41926985/article/details/105627049重写,代码部分为本人编辑 代码要求 应用动态规划方法&#xff0c;求解投资问题&#xff0c;实现下面的例子。 #define MAX_N 4 //最大投资项目数目 #define MAX_M 5 //最大投资钱数(万元) /…

文献阅读:SPACEL:基于深度学习的空间转录组结构表征

文献介绍 「文献题目」 SPACEL: deep learning-based characterization of spatial transcriptome architectures 「研究团队」 瞿昆&#xff08;中国科学技术大学&#xff09; 「发表时间」 2023-11-22 「发表期刊」 Nature Communications 「影响因子」 16.6 「DOI」 10.…

ICode国际青少年编程竞赛- Python-1级训练场-基础训练2

ICode国际青少年编程竞赛- Python-1级训练场-基础训练2 1、 a 4 # 变量a存储的数字是4 Dev.step(a) # 因为变量a的值是4&#xff0c;所以Dev.step(a)就相当于Dev.step(4)2、 a 1 # 变量a的值为1 for i in range(4):Dev.step(a)Dev.turnLeft()a a 1 # 变量a的值变为…

[C++初阶]string类

1. 为什么要学习string类 1.1 C语言中的字符串 C语言中&#xff0c;字符串是以\0结尾的一些字符的集合&#xff0c;为了操作方便&#xff0c;C标准库中提供了一些str系列的库函数&#xff0c; 但是这些库函数与字符串是分离开的&#xff0c;不太符合OOP(面向对象)的思想&…

JAVA中的lambda表达式(无废话)

Lambda表达式是Java SE 8中一个重要的新特性。 它是一种语法形式&#xff0c;可以代码书写更加精炼。 用人话说就是把原来的代码变得很短。 这部分的内容是非常简单的。 一、函数式接口 想要理解lambda表达式&#xff0c;首先要了解函数式接口。 关于接口的知识请查阅&am…

浏览器中不能使用ES6的扩展语法...报错

浏览器大多数已经支持ES6&#xff08;ECMAScript 2015&#xff09;的扩展语法&#xff08;...&#xff09;&#xff0c;包括Chrome、Firefox、Safari和Edge等。然而&#xff0c;如果你在某些浏览器中遇到无法使用扩展语法的问题&#xff0c;可能是由以下原因导致的&#xff1a;…

ngrinder项目-本地调试遇到的坑

前提-maven mirrors配置 <mirrors><!--阿里公有仓库--><mirror><id>nexus-aliyun</id><mirrorOf>central</mirrorOf><name>Nexus aliyun</name><url>http://maven.aliyun.com/nexus/content/groups/public</ur…

每周打靶VulnHub靶机-DOUBLETROUBLE_ 1

doubletrouble: 1靶机传送门 get flags 靶机名为 双重麻烦&#xff0c;可能会繁琐一点 1.信息搜集 使用nmap进行域内存活主机扫描继续扫描其开放端口开放了22(ssh)、80(http)端口使用浏览器访问其80端口是一个登录页面&#xff0c;继续扫描其 敏感目录dirsearch -u [http://19…

通过helm在k8s上安装minio

1 helm安装minio 1.1 下载minio 添加仓库 helm repo add bitnami https://charts.bitnami.com/bitnami 将minio拉取下来 helm pull bitnami/minio --version 版本号 解压到本地开始编辑配置文件 tar -zxf minio-xxx.tgz [rootk8s-master01 minio]# vi values.yaml 1.2…

拼多多多多搜索推广技巧

拼多多多多搜索推广技巧主要包括以下几个方面&#xff1a; 拼多多推广可以使用3an推客。3an推客&#xff08;CPS模式&#xff09;给商家提供的营销工具&#xff0c;由商家自主设置佣金比例&#xff0c;激励推广者去帮助商家推广商品链接&#xff0c;按最终有效交易金额支付佣金…

Docker新建容器 修改运行容器端口

目录 一、修改容器的映射端口 二、解决方案 三、方案 一、修改容器的映射端口 项目需求修改容器的映射端口 二、解决方案 停止需要修改的容器 修改hostconfig.json文件 重启docker 服务 启动修改容器 三、方案 目前正在运行的容器 宿主机的3000 端口 映射 容器…

重要!!!方法的进阶使用------回调函数

参考资料&#xff1a; 参考视频 下面所有举的例子都在参考demo中 概述&#xff1a; 回调函数很简单&#xff0c;就是对普通方法参数的类型的拓展&#xff0c;其实是对普通方法的深层应用&#xff1b;回调函数其实就是将含有执行方法类的实例&#xff0c;以参数的形式传入到方…

集成学习算法:AdaBoost详解以及代码实现

本文尽量从一个机器学习小白或是只对机器学习算法有一个大体浅显的视角入手&#xff0c;尽量通俗易懂的介绍清楚AdaBoost算法&#xff01; 一、AdaBoost简介 AdaBoost&#xff0c;是英文"Adaptive Boosting"&#xff08;自适应增强&#xff09;的缩写&#xff0c;由…

【Linux】进程间通信 - 管道

文章目录 1. 进程间通信介绍1.1 进程间通信目的1.2 进程间通信发展1.3 进程间通信分类 2. 管道2.1 什么是管道2.2 匿名管道2.3 用 fork 来共享管道原理2.4 站在文件描述符角度 - 深入理解管道2.5 站在内核角度 - 管道本质2.6 管道读写规则2.7 管道特点 3. 命名管道3.1 匿名管道…