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.rhkb.cn/news/244958.html

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

相关文章

Unity中UGUI在Mask剪裁粒子特效的实现

在Unity使用Mask是剪裁不了粒子特效的,之前有想过RenderTexture来实现,不过使用RenderTexture不适合用于很多个特效,因为RenderTexture依赖Camera的照射,如果在背包中每种道具都有不同的特效,那使用RenderTexture则需要…

PySide6/PyQt6中Qt窗口标志/窗口属性汇总,如何正确的设置窗口标志/窗口属性

文章目录 📖 介绍 📖🏡 环境 🏡📒 使用方法 📒📚 窗口标志汇总📚 窗口属性汇总📝 使用方法📝 注意事项⚓️ 相关链接 ⚓️📖 介绍 📖 在Qt框架中,窗口标志(window flags)是用于控制窗口的各种属性和行为的强大工具。它们通过设置窗口的属性,如边框…

【江科大】STM32:USART串口(理论部分)上

串口 全双工:可以进行同步通信 单端信号:信号线传输的就是单端信号。(也就是与地线(GND)的电势差) 缺点:防干扰能力差 原因:当信号从A点传输到B点,理想条件是A&#xff0…

nextjs中beforePopState使用

在某些情况下,希望监听popstate并在路由器对其进行操作之前执行某些操作。可以使用beforePopState。 在Next.js中,beforePopState是一个可选的生命周期函数,用于在浏览器的历史记录发生更改之前执行一些操作。具体来说,beforePopS…

Git学习笔记(第9章):国内代码托管中心Gitee

目录 9.1 简介 9.1.1 Gitee概述 9.1.2 Gitee帐号注册和登录 9.2 VSCode登录Gitee账号 9.3 创建远程库 9.4 本地库推送到远程库(push) 9.5 导入GitHub项目 9.6 删除远程库 9.1 简介 9.1.1 Gitee概述 众所周知,GitHub服务器在国外,使用GitHub作为…

BurpSuite Pro 2023.12.1.2下载与破解-最新版BurpSuite Pro

本文在我的博客地址是:https://h4cker.zip/post/f05ae2e66da503f6383dffe48cdf5bac 上一次BurpSuite的分享还是在2020年 由于CSDN有防盗链,我自己的博客都无法访问这篇博文的图片了 至于为什么再写一次,是因为我看到群里这张图:…

如何应对强硬的项目干系人?

一、强硬项目干系人的特征和挑战 在项目管理中,强硬项目干系人往往具有坚定的立场、强烈的主张和不易妥协的特点,这给项目团队带来了诸多挑战。他们可能对项目目标、进度、成本等方面持有严格要求,甚至可能过度干涉项目的具体执行过程&#x…

小程序直播项目搭建

项目功能: 登录实时聊天点赞功能刷礼物取消关注用户卡片直播带货优惠券直播功能 项目启动: 1 小程序项目创建与配置: 第一步 需要登录小程序公众平台的设置页面进行配置: 首先需要是企业注册的才可以个人不能开通直播功能。服务类…

“智汇语言·驭领未来”——系列特辑:LLM大模型信息获取与企业应用变革

“智汇语言驭领未来”——系列特辑:LLM大模型信息获取与企业应用变革 原创 认真的飞速小软 飞速创软 2024-01-16 09:30 发表于新加坡 本期引言 LLM(Large Language Model)大型语言模型以其自然语言理解和生成能力,正以前所未有的…

有关软件测试的,任何时间都可以,软件测试主要服务项目:测试用例 报告 计划

有关软件测试的,任何时间都可以,软件测试主要服务项目: 1. 测试用例 2. 测试报告 3. 测试计划 4. 白盒测试 5. 黑盒测试 6. 接口测试 7.自动…

实现自己的mini-react

实现自己的mini-react 创建运行环境实现最简单mini-react渲染dom封装创建虚拟dom节点封装函数封装render函数对齐react 调用方式使用 jsx 任务调度器&fiber架构封装一个workLoop方法 统一提交&实现 function component统一提交实现支持 function component 进军 vdom 的…

源码篇--Redis 五种数据类型

文章目录 前言一、 字符串类型:1.1 字符串的编码格式:1.1.1 raw 编码格式:1.1.2 empstr编码格式:1.1.3 int 编码格式:1.1.4 字符串存储结构展示: 二、 list类型:2.1 List 底层数据支持:2.2 List 源码实现:2.3 List 结构…

canvas绘制欧盟盟旗(European Union Flag)

查看专栏目录 canvas实例应用100专栏,提供canvas的基础知识,高级动画,相关应用扩展等信息。canvas作为html的一部分,是图像图标地图可视化的一个重要的基础,学好了canvas,在其他的一些应用上将会起到非常重…

记一次SPI机制导致的BUG定位【不支持:http://javax.xml.XMLConstants/property/accessExternalDTD】

1、前因 今天在生产环境启用了某个功能,结果发现有个文件上传华为云OBS失败了,报错如下: Caused by: java.lang.IllegalArgumentException: 不支持:http://javax.xml.XMLConstants/property/accessExternalDTDat org.apache.xal…

react中数据不可变

先看官网 一、不可变数据的概念 不可变数据意味着数据一旦创建,就不能被更改。在React中,每次对数据的修改都会返回一个新的数据副本,而不会改变原始数据。这种方式确保了数据的稳定性和一致性。 二、Props中的不可变数据 在React中&#xf…

OpenTCS IDEA 全流程搭建和运行指南

OpenTCS IDEA 全流程搭建和运行指南 JDK安装下载JDK版本 openTCS源码下载IDEA 打开运行查看下载源码中gradle版本号下载gradle 二进制文件配置IDEA Gradle本地仓库IDEA打开openTCS项目运行顺序 JDK安装 下载JDK版本 JDK网址 注意: 请下载官方文档标准的java13JDK o…

ubuntu20根目录扩容

ubuntu根目录/ 或者 /home文件夹有时出现空间满了的情况,可以用gparted工具进行空间的重新分配。 首先,如果你是双系统,需要从windows系统下磁盘压缩分配一部分未使用的空间给ubuntu,注意压缩的空间要邻接ubuntu所在盘的位置。 …

图像旋转角度计算并旋转

#!/usr/bin/python3 # -*- coding: utf-8 -*- import cv2 import numpy as np import timedef Rotate(img, angle0.0,fill0):"""旋转:param img:待旋转图像:param angle: 旋转角度:param fill:填充方式,默认0黑色填充:return: img: 旋转后…

纯前端实现了Excel文件转JSON和JSON转Excel下载

需求前提: 上传Excel文件,并将Excel文件的内容拿出来转换为JSON本地定义JSON数据,然后将它封装后转换为Excel文件下载 安装依赖 这两个功能是借助xlsx包实现的,所以需要先安装xlsx包: npm install xlxs依赖引用 i…

【GitHub项目推荐--一款美观的开源社区系统】【转载】

推荐一款开源社区系统,该系统基于主流的 Java Web 技术栈,如果你是一名 Java 新手掌握了基本 JavaEE 框架知识,可以拿本项目作为练手项目。 开源社区系统功能还算完善包含发布帖子、发布评论、私信、系统通知、点赞、关注、搜索、用户设置、…