JVM虚拟机的垃圾回收器(面试题)

news2024/9/30 5:26:14

 1.什么是垃圾回收

        垃圾回收主要说的是java会自动把程序在运行过程中产生的一些没有用的对象给回收掉,这样可以避免内存的浪费。

        java主要是通过一个叫“根可达”的算法来识别这个对象是否可以被回收的,然后回收的算法也主要有三种:标记清除,拷贝,标记压缩。
        标记清除:在内存里面,找到可以回收的对象,然后直接删除,但是这样会导致内存碎片化。
        拷贝:就是在内存使用的时候,只使用一半的内存,比如说有一块内存,分成两半,分别是A,B。一开始B内存是没有使用的,然后在A内存里面找到有用的对象,直接拷贝到b内存里面去,完事之后,直接把A内存里面的数据给删掉。这样的效率比较高,但是浪费内存空间。
        标记压缩:在内存里面,先把没有用的对象给回收掉,然后重新把有用的对象进行排序,这样内存里面的对象是有序的。但是他的效率比较低。

2.GC算法

        1. 在这个三种回收算法的基础上,出现了十几种垃圾回收器。

        2. GC的演化过程:主要随着内存的不断增长,而陆续出现新的垃圾回收器。

        3. 在java1.8里面主要是分代算法,分代算法可以说是由拷贝算法演变而来,分代算法的jvm垃圾回收器有6个,分代算法里面有新生代和老年代,新生代有伊甸园区和幸存者区,其中幸存者区有两个区域,他们之间的默认比例是8比1比1

     
 
        4.首先新创建的对象会在伊甸园区,等这个区的容量满了之后,进行垃圾回收,会把存活的对象放到幸存者1区,然后直接清空伊甸园区,当第二次进行垃圾回收的时候,会把伊甸园区里面存活的对象跟幸存者1区的对象直接放到幸存者2区,并且同时清除伊甸园区跟幸存者1区,第三次垃圾回收的时候,会把伊甸园区里面存活的对象跟幸存者2区的对象直接放到1区,然后进行清空操作,在进行垃圾回收的时候会重复这个操作,然后满足一定条件的对象,会被转移到老年代里面

3.遇到的问题

        以上这个是最简单的垃圾回收的流程,但是有一个问题,那就是在早期回收垃圾的时候,业务线程是会暂停的,回收垃圾的线程在运行(进行垃圾回收),也就是说,在回收垃圾的过程中,很多线程都是暂停的,那这样的话,应用的响应时间就会变慢。

        举个例子:有用户在下单的时候,应用的运行内存满了,jvm进行垃圾回收,那用户下单时候就会被卡住,所以这个响应时间就会变慢(在系统里面,比较重要的两点,第一个是吞吐量,第二个是响应时间,一般我们在开发里面,进行的JVM调优一般都是调优响应时间)

        而且当内存比较大的时候,一个线程进行垃圾回收会比较慢(可以理解为你一个人收拾100平米的房子,会很吃力),所以后面就演变出了多线程来进行垃圾回收,但是这个多线程也不是越多越好,因为会涉及到cpu的上下文切换,还有就是当你的电脑是四核,那你设置5个线程,那这个时候的效果就不是很好,所以就出现的了CMS回收器

4.CMS回收器跟三色算法

        CMS回收器(并发垃圾回收):举个例子,早期的垃圾回收器是业务线程执行,要回收垃圾的时候,垃圾回收线程执行,业务线程暂停。那这个CMS就是垃圾回收线程一起参与你的业务,如果产生垃圾,也不用你的线程暂停,直接就把垃圾回收掉。

        但是CMS垃圾回收器有一个问题,那就是回收线程在标记了某一个对象是否为垃圾之后,由于cpu的上下文切换导致了回收线程暂停了,那么回收线程重新运行之后,如何判断标记的对象的状态是否改变。因为有可能不是垃圾的对象,在回收线程暂停的过程中,变成了垃圾,那么为了解决这个问题,就有了三色标记算法。

        三色标记算法:三色表示的是对象的三个状态属性有白,黑,灰三种颜色(白色表示:还没有被垃圾回收器扫描的对象,黑色表示:对象本身和对象的成员变量都已经被扫描了,灰色表示:对象本身已经被扫描,但是成员变量还没扫描完),这个算法主要是用来标记活动跟要回收的对象,可以让jvm不发生或者在remark阶段发生一次stw,在清除的时候,是清除白色标记的对象。

        在CMS跟G1回收器里面,都用到了这个三色标记法,但是使用三色标记法会有一个漏标的问题,CMS跟G1的处理方法都不一样。

        CMS是通过写屏障的方法,就是当已经标记了黑色的对象,当他有某个成员变量指向了白色标记对象引用的时候,把这个黑色标记变成灰色标记,但这样还是有一个并发标记,产生漏标的问题,这个算得上是一个比较隐蔽的bug,但是造成问题也是比较严重的。

        举个例子:在回收线程标记A对象的时候,A对象指向B对象,B对象指向C对象,其中A对象还有两个成员变量A1,A2,在回收线程扫描完了A对象的A1,还没来得及扫描A2的时候,回收线程暂停了,然后在业务层面,B对象指向了null,然后A1指向了D对象,那这个时候,通过写屏障,会把A对象的标记变成灰色,然后回收线程继续运行,开始扫描完A2,完事之后会把A标记成了黑色,那这个时候,D对象就没办法被标记,所以D对象会被清除,为了解决这个问题,CMS在最后的remark阶段,必须从头扫描一遍,那这个时候就会产生stw

        G1使用了SATB来解决这个漏标的问题,就是灰色标记的对象指向白色标记的对象,当这个指向的关系消失的时候,进行一个快照,把白色标记的对象放到GC的堆栈里面,然后在堆栈里面查询,如果有对象引用了这个白色标记的对象,那就把这个白色标记的对象标记成灰色

        还有就是在java里面有四种引用类型,强引用:在代码里面直接new出来的对象属于一个强引用,如果一个对象具有强引用,JVM就没有办法对它进行回收,当内存空间不够的时候就会报OOM错误,软引用:如果一个对象只具备软引用,那么当内存空间不够的时候,JVM就会把这个对象进行回收,弱引用:如果一个对象只具备了弱引用,那么被jvm的gc线程检测到了,这个对象就会被回收

        建议:在jdk1.8以后,把CMS升级为G1回收器 ,G1解决了CMS的stw问题

5.推荐视频

2.自动化回收_哔哩哔哩_bilibili
强烈推荐看下这个视频,会对底层原理理解得更加透彻

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

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

相关文章

QT c++和qml交互实例

文章目录 一、demo效果图二、c和qml交互的基本方式1、qml访问C类对象 三、关键代码1、工程结构图2、c代码MainWindow.cppMainQuickView.cppStudentInfoView.cppStudentInfoModel.cpp 3、qml代码main.qmlMainQuickTopRect.qmlMainQuickMiddleRect.qmlMainQuickMiddleTableRect.q…

服务器cpu占用很高如何排查问题

前段时间,运维监控发现有个项目cpu占用很高,并且还在持续不断增长,服务不能正常响应,如下图: 在服务器上面安装了arthas,下载地址: https://alibaba.github.io/arthas/arthas-boot.jar 我使用了…

Linux stm32串口下载程序

一、工具 使用stm32flash进行串口下载 二、stm32flash安装 sudo apt-get install stm32flash 三、查看串口设备名称 先拔掉串口运行下面指令,获得所有设备名称,插上串口再运行一次,新增的就是串口设备名称,记住串口设备名称,以…

【信息论与编码】习题-判断题-第一部分

目录 判断题1. 对于N个对立并联信道,其信道容量CN2. 汉明码是一种线性分组码。3. 某一信源,不管它是否输出符号,只要这些符号具有某些概率特性,就有信息量。4. 若检错码的最小距离为dmin,则可以检测出任意小于等于dmin…

集团企业OA办公协同平台建设方案

一、企业对协同应用的需求分析 实现OA最核心、最基础的应用 业务流转:收/发文、汇报、合同等各种审批事项的业务协作与办理 信息共享:规章制度、业务资料、共享信息资源集中存储、统一管理 沟通管理:电子邮件、手机短信、通讯录、会议协作等…

期货日数据维护与使用_日数据维护_日数据更新

目录 写在前面: 下载日数据 下载“新增合约”日数据 下载“待更新合约”日数据 日数据文件 “选择日数据所在目录”按钮点击 “执行”按钮点击 sqlite3代码 按钮点击后执行的代码 子线程代码 写在前面: 本文默认已经创建了项目,如…

Archlinux下自启动rclone mount

路径: /etc/systemd/system/rclonemount.service [Unit] Descriptionrclonemount Requiresnetwork-online.target.wants Afteralist.service[Service] Typesimple ExecStartPre/bin/mkdir -p /media ExecStart/usr/bin/rclone mount \aliyun: /media \--config /ro…

Docker学习与应用(五)-DockerFile

1、DockerFile 1)DockerFile介绍 dockerfile是用来构建docker镜像的文件!命令参数脚本! 构建步骤: 1. 编写一个dockerfile文件 2. docker build 构建称为一个镜像 3. docker run运行镜像 4. docker push发布镜像(D…

2024最新前端源码分享(附效果图及在线演示)

分享10款非常有趣的前端特效源码 其中包含css动画特效、js原生特效、svg特效以及小游戏等 下面我会给出特效样式图或演示效果图 但你也可以点击在线预览查看源码的最终展示效果及下载源码资源 粒子文字动画特效 基于canvas实现的粒子文字动画特效 会来回切换设定的文字特效 图…

Docker学习与应用(四)-容器数据卷

1、容器数据卷 1)什么是容器数据卷 docker的理念回顾 将应用和环境打包成一个镜像! 数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!需求:数据可以持久化 MySQL,容器删…

java推荐系统:好友推荐思路

1.表的设计 表里面就两个字段,一个字段是用户id,另外一个字段是好友id,假如A跟B互为好友,那在数据库里面就会有两条数据 2.推荐好友思路 上面的图的意思是:h跟a的互为好友,a跟b,c&am…

webgl调试之排查内存泄漏

内存泄漏自然而然是要看内存是不是涨了 然后我们如何确认泄露了呢,我们需要把代码梳理清楚,知道哪个时机,在delete,在create,那么这个时候,按道理,delete了n个对象,create了N个对象&…

[Excel]如何找到非固定空白格數列的條件數據? 以月份報價表單為例

在群組中看到上述問題,研判應是一份隨月份變動的產品報價表單,空白欄可能表示該月份價格與上個月份一致。這個問題是需要取得最近一次單價和倒數第二次單價,常用且實務的excel案例值得紀錄。 最近一次單價: INDEX($B2:$G2,1,LARGE(IF(ISBLAN…

贯穿设计模式-享元模式思考

写享元模式的时候,会想使用ConcurrentHashMap来保证并发,没有使用双重锁会不会有问题?但是在synchronize代码块里面需要尽量避免throw异常,希望有经验的同学能够给出解答? 1月6号补充:没有使用双重锁会有问…

【Qt- C++ Qml 交互】

Qt编程指南 VX:hao541022348 ■ 将C对象注册到 QML中,在QML使用C对象(Q_INVOKABLE宏)■ C对象注册到元对象系统■ Q_INVOKABLE 宏■ 演示步骤 ■ 将C对象注册到 QML中,在QML使用C对象(Q_PROPERTY宏 属性绑定…

SpringCloud系列篇:核心组件之负载均衡组件

🥳🥳Welcome Huihuis Code World ! !🥳🥳 接下来看看由辉辉所写的关于SpringCloud的相关操作吧 目录 🥳🥳Welcome Huihuis Code World ! !🥳🥳 一.负载均衡组件是什么 二.负载均衡…

PDF文档转换工具箱流量主小程序开发

PDF转换小助手,不仅是文件格式转换的利器,更是一位得力的助手。它精通PDF与各类文档间的自由转换,如Word、Excel、PowerPoint等。 转换选项丰富多样,满足您对文件保护、页面设置、图像品质等细致要求。处理大量文件?…

软件工程:数据流图相关知识和多实例分析

目录 一、数据流图相关知识 1. 基本介绍 2. 常用符号 3. 附加符号 二、数据流图实例分析 1. 活期存取款业务处理系统 2. 工资计算系统 3. 商业自动化系统 4. 学校人事管理系统 5. 教材征订系统 6. 高考录取统分子系统 7. 订货系统 8. 培训中心管理系统 9. 考务处…

模仿Activiti工作流自动建表机制,实现Springboot项目启动后自动创建多表关联的数据库与表的方案

文/朱季谦 熬夜写完,尚有不足,但仍在努力学习与总结中,而您的点赞与关注,是对我最大的鼓励! 在一些本地化项目开发当中,存在这样一种需求,即开发完成的项目,在第一次部署启动时&…

【视频图像篇】模糊图像处理之车辆运动造成的字体模糊还原

【视频图像篇】模糊图像处理之车辆运动造成的字体模糊还原 处理车辆运动过程中造成字体模糊重影的图像处理过程—【蘇小沐】 0、目录 1、实验环境 2、路径 3、去运动模糊(有噪声) 4、其它参数 5、结果展示 1、实验环境 系统环境Windows 11 专业…