JVM篇--垃圾回收器高频面试题

1 你知道哪几种垃圾收集器,各自的优缺点是啥,重点讲下cms和G1,包括原理,流程,优缺点?

1)首先简单介绍下 有以下这些垃圾回收器
Serial收集器单线程的收集器,收集垃圾时,必须stop the world,使用复制算法。
ParNew收集器Serial收集器的多线程版本,也需要stop the world,复制算法。
Parallel Scavenge收集器: 新生代收集器,复制算法的收集器,并发的多线程收集器,目标是达到一个可控的吞吐量。如果虚拟机总共运行100分钟,其中垃圾花掉1分钟,吞吐量就是99%。
Serial Old收集器: 是Serial收集器的老年代版本,单线程收集器,使用标记整理算法。
Parallel Old收集器: 是Parallel Scavenge收集器的老年代版本,使用多线程,标记-整理算法。
CMS(Concurrent Mark Sweep) 收集器是一种以获得最短回收停顿时间为目标的收集器,标记清除算法,运作过程:初始标记,并发标记,重新标记,并发清除,收集结束会产生大量空间碎片。

G1收集器标记整理算法实现,运作流程主要包括以下:初始标记,并发标记,最终标记,筛选标记。不会产生空间碎片,可以精确地控制停顿。(重点)

2)CMS收集器和G1收集器的区别:

  1. CMS收集器是老年代的收集器,可以配合新生代的Serial和ParNew收集器一起使用;
  2. G1收集器收集范围是老年代和新生代,不需要结合其他收集器使用;
  3. CMS收集器以最小的停顿时间为目标的收集器;
  4. G1收集器可预测垃圾回收的停顿时间
  5. CMS收集器是使用“标记-清除”算法进行的垃圾回收,容易产生内存碎片
  6. G1收集器使用的是“标记-整理”算法,进行了空间整合,降低了内存空间碎片。

2详细介绍一下 CMS 垃圾回收器?

首先CMS垃圾收集器是一种
1 老年代的垃圾收集器
2 是以牺牲吞吐量为代价来获取最短回收停顿时间的垃圾回收器
3 多线程并发的标记-清除算法所以在gc的时候会产生大量的内存碎片,当剩余内存不能满足程序运行要求时,系统将会出现 Concurrent Mode Failure,临时 CMS 会采用 Serial Old 回收器进行
垃圾清除,此时的性能将会被降低。

CMS 工作机制相比其他的垃圾收集器来说更复杂。
整个过程分为以下 4 个阶段:

初始标记
只是标记一下 GC Roots 能直接关联的对象,速度很快,仍然需要暂停所有的工作线程。

并发标记
进行 GC Roots 跟踪的过程,和用户线程一起工作,不需要暂停工作线程。

重新标记
为了修正在并发标记期间,因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,仍然需要暂停所有的工作线程。

并发清理
清除 GC Roots 不可达对象,和用户线程一起工作,不需要暂停工作线程。由于耗时最长的并发标记和并发清除过程中,垃圾收集线程可以和用户现在一起并发工作, 所以总体上来看CMS 收集器的内存回收和用户线程是一起并发地执行。

3 详细介绍一下 G1 垃圾回收器?

首先G1垃圾收集器相比于CMS垃圾收集器,有两个突出的优点
1 基于标记整理算法,不产生内存碎片
2 可以按照按照用户预期的停顿时间进行执行,也就是说在不牺牲吞吐量的情况下,实现低停顿垃圾回收

G1垃圾回收器的实现原理:G1将Java堆划分为多个大小相等的独立区域(Region),一般Region大小等于堆大小除以2048,比如堆大小为4096M,则Region大小为2M,当然也可以用参数"-XX:G1HeapRegionSize"手动指定Region大小

G1垃圾收集器的特点:
1 使用了标记-整理算法,无内存碎片产生
2 无分代概念但是有内存分区策略,即G1它将新生代和老年代的这种物理空间划分取消了,但是G1 采取了内存分区策略,将堆内存划分为大小固定的几个独立区域。
而具体的分区 可以分为 新生代区域,老年代区域,大对象区域
G1垃圾收集器对于对象什么时候会转移到老年代跟之前讲过的原则一样,唯一不同的是对大对象的处理,G1有专门分配大对象的Region叫Humongous区,而不是让大对象直接进入老年代的Region中。在G1中,大对象的判定规则就是一个大对象超过了一个Region大小的50%,比如按照上面算的,每个Region是2M,只要一个大对象超过了1M,就会被放入Humongous中,
而且一个大对象如果太大,可能会横跨多个Region来存放。
Full GC的时候除了收集年轻代和老年代之外,也会将Humongous区一并回收

G1收集器一次GC的过程:(主要指Mixed GC)
初始标记暂停所有的其他线程,并记录下gc roots直接能引用的对象,速度很快 ;
并发标记:同CMS的并发标记
最终标记:同CMS的重新标记
筛选回收(Cleanup,STW):筛选回收阶段**1 首先对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿STW时间(可以用JVM参数 -XX:MaxGCPauseMillis指定)来制定回收计划,**比如说老年代此时有1000个Region都满了,但是因为根据预期停顿时间,本次垃圾回收可能只能停顿200毫秒,那么通过之前回收成本计算得知,可能回收其中800个Region刚好需要200ms,那么就只会回收800个Region(Collection Set,要回收的集合),说白了就是尽量把GC导致的停顿时间控制在我们指定的范围内
这个阶段其实也可以做到与用户程序一起并发执行,但是因为只回收一部分Region,时间是用户可控制的,而且停顿用户线程将大幅提高收集效率。

4 新生代垃圾回收器和老年代垃圾回收器都有哪些?有什么区别?

新生代回收器:Serial、ParNew、Parallel Scavenge
老年代回收器:Serial Old、Parallel Old、CMS
整堆回收器:G1
新生代垃圾回收器一般采用的是复制算法
复制算法的优点是效率高,缺点是内存利用率低

老年代回收器一般采用的是标记-整理的算法进行垃圾回收。
要注意一点:老年代垃圾回收算法的速度至少比新生代垃圾回收算法的速度慢10倍。如果系统频繁的出现老年代中的full gc,会导致系统性能严重影响,出现频繁卡顿等情况
总结经验所谓JVM优化,就是尽可能让对象都在新生代里分配和回收,尽量别让太多对象频繁进入老年代,避免频繁对老年代进行垃圾回收,同时给系统充足的内存大小,避免新生代频繁的进行垃圾回收。

5 什么时候会触发FullGC?

1 首先我们要理解fullGC其实就是对老年代进行垃圾回收,同时也一般会对新生代进行垃圾回收;

2 那么做fullGC的目的是什么呢?
就是必须得把老年代里没人引用的对象给回收掉,这样才有可能让minor gc 后存活的对象进入到老年代

3因此我们就能推出哪些情况会触发FullGC?
除直接调用System.gc外,触发Full GC执行的情况有如下三种。
1. 年轻代中需要进行垃圾回收的对象过多。即在执行minor gc之前判断 老年代的内存空间小于新生代的所有对象总和,或者说也没有设置 “-XX: -HandlePromotionFailure” 这个参数,那么此时就会直接执行一次full gc,就是对老年代进行一次垃圾回收,(腾出一些内存空间,然后再执行minorGC );

2. 年轻代有大对象频繁进入到老年代
老生代空间只有在年轻代对象转入及创建为大对象、大数组时才会出现不足的现象,当执行Full GC后空间仍然不足,则抛出如下错误:
java.lang.OutOfMemoryError: Java heap space
为避免以上两种状况引起的FullGC,调优时应尽量做到让对象在Minor GC阶段被回收、让对象在新生代多存活一段时间及不要创建过大的对象及数组。

3. 永久代(元空间)已满
老年代的内存空间小于新生代的所有对象总和,或者说也没有设置 “-XX: -HandlePromotionFailure” 这个参数,那么此时就会直接执行一次full gc,就是对老年代进行一次垃圾回收,腾出一些内存空间,然后再执行minorGC

6 方法区如何进行垃圾回收?

方法区的垃圾收集主要回收两部分内容:1) 运行时常量池中废弃的常量;2 )不再使用的类型。
1 运行时常量池中废弃的常量:首先看常量 主要包括字面量和符号引用,其实只要常量池中的常量没有被任何地方引用,就可以被回收。
2 而一个类型的回收就包括:

  1. 该类所有的实例都已经被回收
  2. 加载该类的类加载器已经被回收
  3. 该类对应的java.lang.Class对象没有在任何地方被引用

7 Minor GC过后可能对应哪几种情况?

  1. 第一种可能,Minor GC过后,剩余的存活对象的大小,是小于Survivor区的大小的,那么此时存活对象进入Survivor区域即可。

  2. 第二种可能,Minor GC过后,剩余的存活对象的大小,是大于 Survivor区域的大小,但是是小于老年代可用内存大小的,此时就直接进入老年代即可。

  3. 第三种可能,很不幸,Minor GC过后,剩余的存活对象的大小,大于了Survivor区域的大小,也大于了老年代可用内存的大小。此时老年代都放不下这些存活对象了,就会发生“Handle Promotion Failure”的情况,这个时候就会触发一次“Full GC”。区域即可。的,此时就直接进入老年代即可。

8 哪些情况下Minor GC后的对象会进入老年代?

1 就是在新生代躲过15次gc的时候,就会进入到老年代
2 当进行minorGC 后,仍然存活的对象无法在servior区无法容纳,也会被转移到老年代

9 什么场景适合使用G1?

  1. 50%以上的堆被存活对象占用
  2. 对象分配和晋升的速度变化非常大
  3. 垃圾回收时间特别长,超过1秒
  4. 8GB以上的堆内存(建议值)
  5. 停顿时间是500ms以内

10 简单介绍下 zgc

ZGC收集器(-XX:+UseZGC)是一款在jdk11中引入的低延迟的垃圾回收器,它的特点主要包括
1 支持TB量级的堆。
2 最大GC停顿时间不超过10ms,之所以能做到这一点是因为它的停顿时间主要跟Root扫描有关,而Root数量和堆大小是没有任何关系的。
3 基于读屏障、 颜色指针等技术来实现可并发的标记-整理算法
在这里插入图片描述

ZGC存在的问题

ZGC最大的问题是浮动垃圾。因为 ZGC没有分代概念,每次都需要进行全堆扫描,导致一些“朝生夕死”的对象在一次的停顿时间内没能及时的被回收。
说白了虽然说ZGC的停顿时间是在10ms以下非常短,但是ZGC的执行时间还是远远大于这个时间的。假如ZGC全过程需要执行10分钟,在这个期间由于对象分配速率很高,将创建大量的新对象,这些对象很难进入当次GC,所以只能在下次GC的时候进行回收,这些只能等到下次GC才能回收的对象就是浮动垃圾。

11 如何选择垃圾收集器?

  1. 优先调整堆的大小让服务器自己来选择
  2. 如果内存小于100M,使用串行收集器
  3. 如果是单核,并且没有停顿时间的要求,串行或JVM自己选择
  4. 如果允许停顿时间超过1秒,选择并行或者JVM自己选
  5. 如果响应时间最重要,并且不能超过1秒,使用并发收集器
  6. 4G以下可以用parallel,4-8G可以用ParNew+CMS,8G以上可以用G1,几百G以上用ZGC

12 什么是三色标记法?

三色标记算法说白了 就是把 Gc roots可达性分析遍历对象过程中遇到的对象, 按照“是否访问过”这个条件标记成以下三种颜色:
黑色: 表示对象已经被垃圾收集器访问过, 且这个对象的所有引用都已经扫描过。 黑色的对象代表已经扫描过, 它是安全存活的, 如果有其他对象引用指向了黑色对象, 无须重新扫描一遍。 黑色对象不可能直接(不经过灰色对象) 指向某个白色对象。
灰色: 表示对象已经被垃圾收集器访问过, 但这个对象上至少存在一个引用还没有被扫描过
白色: 表示对象尚未被垃圾收集器访问过。 显然在可达性分析刚刚开始的阶段, 所有的对象都是白色的, 若在分析结束的阶段, 仍然是白色的对象, 即代表不可达。–即可达性分析算法还没有分析到该对象
在这里插入图片描述

13 那你知道多标和漏标吗?以及怎么解决呢?

多标:即在标记过程中有gcroot引用的对象之前被扫描过-即为非垃圾对象,但是由于在并发标记结束这部分局部变量被销毁了,这样一来本轮的gc就不会回收该对象,也就是原本应该被回收却没有回收的内存 也称为浮动垃圾,当然浮动垃圾不会对垃圾回收的正确性产生影响,只需要等到下一轮回收中被清理就行

漏标:指的是原本不是垃圾应该被标记为黑色,却没有被标记被当做垃圾进行了回收,这样一来其实就会对垃圾回收的正确性产生影响,而解决漏标有两种方式即增量更新和原始快照STAB
当然cms垃圾回收器和g1垃圾回收再解决漏标问题时的处理方式不同
cms用的是增量更新g1用的是原始快照
那么他们用的不同呢?这主要是因为增量更新它其实会做深度的扫描,也就是CMS会对增量引用的根对象做深度扫描,而cms之所以可以这样做,是因为他只有一块内存,但是g1不同,G1是有很多region组成,这样重新深度扫描对象的话G1的代价会比CMS高,所以G1选择SATB不深度扫描对象,只是简单标记,等到下一轮GC再深度扫描。这样效率也会更高

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

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

相关文章

云贝教育 |【OceanBase】OBCA认证考试预约流程

一、OBCA账号登录/注册,链接 https://www.oceanbase.com/ob/login/mobile?gotohttps%3A%2F%2Fwww.oceanbase.com%2Ftraining%2Fdetail%3Flevel%3DOBCA 注册完之后,请点击右上“登录”进行实名认证 OBCA考试报名链接:https://www.oceanbase.…

stm32cubemx下载以及安装【最新版本傻瓜式教程】

一、官网 https://www.st.com/zh/development-tools/stm32cubemx.html 二、下载【废话不多说,按照图示所圈进行】 没有登录账号的建议先注册登录再进行下载,这样省去后面认证的麻烦。 选择自己电脑对应环境的版本,我的是windows11&#xf…

MSE Nacos:解决敏感配置的安全隐患

作者:察溯 前言 Nacos 简介 Nacos [ 1] 是一个更易于构建云原生应用的配置管理和服务管理平台。Nacos 的配置中心具有众多优势:动态实时更新配置、支持水平扩展的高可用系统架构、API 简单易上手、开源免费、多语言支持、集成度高等。基于以上特点&am…

Html+Css+JavaScript实现完整的轮播图功能

概要 这个案例具备常见轮播图完整的功能,大家可以根据自己的需求去修改; 代码可以直接复制运行,需要安装sass 主要功能: (1)鼠标移入轮播图,左右两边的按钮出现,离开则隐藏按钮&a…

proteus8.15安装教程

proteus8.15安装教程 1.管理员运行 2.一直NEXT到这一步,需要注意,一定要选这一个 3.选中后出现 4.一直下一步到更新 这边结束后准备激活: 1.安装激活插件,先关闭防火墙 2.下一步 3.最后,将数据库放在根目录下 …

从零开始配置pwn环境:sublime配置并解决pwn脚本报错问题

1.sublime安装 Download - Sublime Text ──(holyeyes㉿kali2023)-[~] └─$ sudo dpkg -i sublime-text_build-4169_amd64.deb [sudo] password for holyeyes: Selecting previously unselected package sublime-text. (Reading database ... 409163 files and directori…

huggingface学习 | 云服务器使用hf_hub_download下载huggingface上的模型文件

系列文章目录 huggingface学习 | 云服务器使用git-lfs下载huggingface上的模型文件 文章目录 系列文章目录一、hf_hub_download介绍二、找到需要下载的huggingface文件三、准备工作及下载过程四、全部代码 一、hf_hub_download介绍 hf_hub_download是huggingface官方支持&…

力扣【四数之和】

一、题目描述 18. 四数之和 给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复&#x…

大数据开发之电商数仓(hadoop、flume、hive、hdfs、zookeeper、kafka)

第 1 章:数据仓库 1.1 数据仓库概述 1.1.1 数据仓库概念 1、数据仓库概念: 为企业制定决策,提供数据支持的集合。通过对数据仓库中数据的分析,可以帮助企业,改进业务流程、控制成本,提高产品质量。 数据…

C#中chart控件

C#中chart控件 图表的5大集合 例子 第一步:创建工程 放入chart控件 series集合 选择图标类型 选择绘制曲线的宽度和颜色。 显示数据标签 Title集合 添加标题 调整标题字体:大小和颜色 CharsArea集合 对坐标轴进行说明 设置间隔 设置刻度…

第11章_常用类和基础API拓展练习(字符串相关练习,日期时间API练习,比较器练习,其它API练习)

文章目录 第11章_常用类和基础API拓展练习字符串相关练习1:阅读题1、length说明2、阅读代码,分析结果3、阅读代码,分析结果4、阅读代码,分析结果5、阅读代码,分析结果6、阅读代码,分析结果7、阅读代码&…

【Linux】Linux基本操作(二):rm rmdir man cp mv cat echo

承接上文: 【【Linux】Linux基本操作(一):初识操作系统、ls、cd、touch、mkdir、pwd 】 目录 1.rmdir指令 && rm 指令: rmdir -p #当子目录被删除后如果父目录也变成空目录的话,就连带父目录一…

崩溃了!我说用attach进行问题定位,面试官问我原理

Arthas(阿尔萨斯)是一款开源的Java诊断和监控工具,可以在生产环境中进行实时的应用程序分析和故障排查。Arthas的实现原理主要基于Java Instrumentation API和Java Agent技术。 Java Agent 是 Java 编程语言提供的一种特殊机制,允…

3.php开发-个人博客项目输入输出类留言板访问IPUA头来源

目录 知识点 : 输入输出 配置环境时: 搜索框: 留言板: 留言板的显示(html): php代码显示提交的留言: 写入数据库 对留言内容进行显示: php全局变量-$_SERVER 检测来源 墨…

AMEYA360:航顺HK32AUTO39A—适用车载娱乐系统优化方案

车载娱乐系统,顾名思义最开始其功能主要是为驾驶员和乘客提供娱乐体验,但现在智能座舱时代到来,车载信息娱乐系统已成为“人-车-环境”交互的重要载体,是除了驾驶以外的其他任务的中心。 从功能模块上看,车载娱乐系统从…

【算法练习Day50】下一个更大元素II接雨水

​📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:练题 🎯长路漫漫浩浩,万事皆有期待 文章目录 下一个更大元素II接雨水单调…

9.4 Lambda表达式

9.4 Lambda表达式 1 Lambda语法2. 基于Lambda实现函数式编程3. Stream流式处理 1 Lambda语法 2. 基于Lambda实现函数式编程 3. Stream流式处理

【网站项目】基于SSM的273校园二手交易网站

🙊作者简介:多年一线开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板&#xff…

cesium实现动态围栏

项目中使用到了cesium,需要实现动态的围栏的效果, 在网上也找了好多案例,通过着色器来实现效果,为此也有好多博主也附上了自己的代码,也许是因为使用方法不同,复制代码并修改依旧还是没有通过他们的方式实现效果【着色…

STM32标准库开发——PWM驱动代码

PWM驱动初始化代码 使能定时器二时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);设置定时器时钟源 TIM_InternalClockConfig(TIM2);配置定时器二的时基单元 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_TimeBaseInitStruct.TIM_ClockDivisionTIM_CKD_D…