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再深度扫描。这样效率也会更高

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Flink(十四)【Flink SQL(中)查询】

前言 接着上次写剩下的查询继续学习。 Flink SQL 查询 环境准备: # 1. 先启动 hadoop myhadoop start # 2. 不需要启动 flink 只启动yarn-session即可 /opt/module/flink-1.17.0/bin/yarn-session.sh -d # 3. 启动 flink sql 的环境 sql-client ./sql-client.sh …

Tomcat Notes: Web Security

This is a personal study notes of Apache Tomcat. Below are main reference material. - YouTube Apache Tomcat Full Tutorial,owed by Alpha Brains Courses. https://www.youtube.com/watch?vrElJIPRw5iM&t801s 1、Overview2、Two Levels Of Web Securi…

深入Matplotlib:画布分区与高级图形展示【第33篇—python:Matplotlib】

文章目录 Matplotlib画布分区技术详解引言方法一:plt.subplot()方法二:简略写法方法三:plt.subplots()实例展示添加更多元素 进一步探索Matplotlib画布分区自定义子图布局3D子图结语 Matplotlib画布分区技术详解 引言 Matplotlib是一个强大…

1.6万字全面掌握 BERT:自然语言处理(NLP)从初学到高级的全面指南

BERT(双向编码器表示来自Transformer的模型)是由Google开发的一种革命性的自然语言处理(NLP)模型。它改变了语言理解任务的格局,使机器能够理解语言中的上下文和细微差异。 在本博客中,我们将带您从 BERT …

动态路由协议 - OSPF 基本配置 详解 (反掩码,宣告,三张表,Cost默认值修改 )

目录 预备工作 : 基础配置 : 先启动 OSPF 的进程 : 创建区域 : 宣告 : 查看三张表 邻居表 : 数据库表 : 路由表 : 以下示拓扑为 OSPF 示范 : 第一步…

基于python卷积网络对漫画人物好坏识别-含数据集和代码

数据集介绍,下载本资源后,界面如下: 有一个文件夹一个是存放数据集的文件。 数据集介绍: 一共含有:2个类别,包含:evil, good等。 然后本地的train.txt和val.txt里面存放的是数据集的图片路径和对应的标签。 运行trai…

linux驱动(八):block,net

本文主要探讨210的block驱动和net驱动。 block 随机存取设备且读写是按块进行,缓冲区用于暂存数据,达条件后一次性写入设备或读到缓冲区 块设备与字符设备:同一设备支持块和字符访问策略,块设备驱动层支持缓冲区,字符设备驱动层没有缓冲 块设备单位:扇…

基于python深度学习的颜色识别-含数据集和代码

数据集介绍,下载本资源后,界面如下: 有一个文件夹一个是存放数据集的文件。 数据集介绍: 一共含有:10个类别,包含:black, blue, brown, green, grey, orange, red, violet, white, yellow等。 然后本地的train.txt和…

什么是游戏盾?哪家效果好。

游戏盾是什么呢,很多做游戏开发的客户估计都是听说过的,但是也不是所有的游戏开发者会运用到。因为,游戏盾是针对游戏行业APP业务所推出的高度可定制的网络安全管理解决方案,除了能针对大型DDoS攻击(T级别)进行有效防御外&#xf…

腾讯云com域名注册怎么收费?

腾讯云com域名首年价格,企业新用户注册com域名首年1元,个人新用户注册com域名33元首年,非新用户注册com域名首年元85元一年,优惠价75元一年,com域名续费85元一年。腾讯云百科txybk.com分享腾讯云com域名注册优惠价格&a…

3.postman动态参数、文件上传及断言

一、postman内置动态参数以及自定义的动态参数 postman内置动态参数: {{$timestamp}} 生成当前时间的时间戳 {{$randomint}} 生成0-1000之间的随机数 {{$guid}} 生成随机guid字符串 自定义动态参数: 在请求中pre-req页面下 //手动的获得时间戳 var…

关于索引的最常见的十道面试题

面试题一:索引底层如何实现的? MySQL索引的底层实现是取决于存储引擎的,但是是大部分存储引擎底层都是通过B树实现的,以默认的存储InnoDB为例,底层就是通过B树实现的,如下图所示: B树是一种自平…

NumPy2要来了,但先别急!

B站:啥都会一点的研究生公众号:啥都会一点的研究生 如果你正在使用 Python 编写代码,那么很有可能正在直接或间接地使用 NumPy 如Pandas、Scikit-Image、SciPy、Scikit-Learn、AstroPy…这些都依赖于 NumPy NumPy 2 是一个新的重要版本&am…

网络逻辑示意图工具

现代网络容纳了来自不同供应商的大量设备,支持一系列新技术,并跨越了分布在多个位置的边界,随着网络变得越来越复杂,网络管理员发现越来越难以跟踪网络领域的所有当代进步和发展,这使得网络管理比以往任何时候都更具挑…

Java8的Stream最佳实践

从这一篇文章开始,我们会由浅入深,全面的学习stream API的最佳实践(结合我的使用经验),本想一篇写完,但写着写着发现需要写的内容太多了,所以分成一个系列慢慢来说。给大家分享我的经验的同时&a…

hadoop必记知识点(1)

1.Hadoop是什么,解决什么问题? Hadoop是一个由Apache基金会所开发的分布式系统基础架构。它可以让使用者在普通的硬件上搭建起一个强大的计算集群。Hadoop的特点包括:高可靠性、高扩展性、高容错性、支持大数据和高并发等。Hadoop核心组件包…

python写完程序怎么运行

python有两种运行方式,一种是在python交互式命令行下运行; 另一种是使用文本编辑器直接在命令行上运行。 注:以上两种运行方式均由CPython解释器编译运行。 当然,也可以将python代码写入eclipse中,用JPython解释器运行&#xff0c…

推荐系统|2.4 矩阵分解的目的和效果

文章目录 矩阵分解矩阵分解的必要性和方法隐向量 矩阵分解 矩阵分解的必要性和方法 比如原本是一个 m n m\times n mn规模大小的矩阵,经过分解后可得到两个矩阵一个是 m k m\times k mk,另外一个是 k n k\times n kn,于是总占用空间为 ( m n ) k (mn)\times k…

腾讯云.com域名报价

腾讯云com域名首年价格,企业新用户注册com域名首年1元,个人新用户注册com域名33元首年,非新用户注册com域名首年元85元一年,优惠价75元一年,com域名续费85元一年。腾讯云百科txybk.com分享腾讯云com域名注册优惠价格&a…

【C语言编程之旅 7】刷题篇-函数

第1题 解析 A:错误,一个函数只能返回一个结果 B:正确,将形参存在数组中,修改数组中内容,可以通过数组将修改结果带出去 C:正确,形参如果用指针,最终指向的是外部的实参…