JVM垃圾回收面试题及原理

1. 对象什么时候可以被垃圾器回收

如果一个或多个对象没有任何的引用指向它了,那么这个对象现在就是垃圾,如果定位了垃圾,则有可能会被垃圾回收器回收
在这里插入图片描述

如果要定位什么是垃圾,有两种方式来确定

  • 引用计数法
  • 可达性分析算法

1.1 引用计数法

1.1.1 原理

String demo = new String;

在这里插入图片描述

String demo = null;

在这里插入图片描述

1.1.2 局限

创建实例,互相调用

public class Demo {
Demo instance;
String name;
public Demo(String name)(
this.name = name;Demo a = new Demo"a");
Demo b = new Demo("b™);
a.instance = b;
b.instance = a

在这里插入图片描述

设置a,b为null,互相引用导致ref=1,循环引用,会引发内存泄露

a = null;
b = null

在这里插入图片描述

1.2 可达性分析算法

现在的虚拟机采用的都是通过可达性分析算法来确定哪些内容是垃圾。
在这里插入图片描述

X,Y这两个节点是可回收的

  • Java 虚拟机中的垃圾回收器采用可达性分析来探索所有存活的对象
  • 扫描堆中的对象,看是否能够沿着GC Root 对象为起点的引用链找到该对象,找不到,表示可以回收

1.2.1 哪些对象可以作为GC Root

  • 虚以机栈(栈帧中的本地变量表)中引用的对象
public static void main (Stringll args) {
Demo demo = new Demo);
demo = null;
  • 方法区中类静态属性引用的对象
public static Demo a;
public static void main(Stringl] args) {
Demo b = new Demo);
b.a = new Demo;
b = null;
  • 方法区中常量引用的对象
public static final Demo a = new Demo);
public static void main(String[] args) {
Demo demo = new Demo;
demo = null;
  • 本地方法栈中JNI(即一般说的Native 方法)引用的对象

2. 垃圾回收算法

2.1 标记清除算法

2.1.1 原理

标记清除算法,是将垃圾回收分为2个阶段,分别是标记和清除。

  1. 根据可达性分析算法得出的垃圾进行标记
  2. 对这些标记为可回收的内容进行垃圾回收
    在这里插入图片描述

2.1.2 局限

  • 优点:标记和清除速度较快
  • 缺点:碎片化较为严重,内存不连贯的
    内存分配碎片化对数组存储不友好(数组占用连续的储存空间,难存储大数组)

2.2 标记整理算法

优缺点同标记清除算法,解决了标记清除算法的碎片化的问题,同时,标记压缩算法多了一步,对象移动内存位置的步骤其效率也有有一定的影响
在这里插入图片描述

2.3 复制算法

  • 优点:
    1. 在垃圾对象多的情况下,效率较高
    2. 清理后,内存无碎片
  • 缺点:
    1. 分配的2块内存空间,在同一个时刻,只能使用一半,内存使用率较低(一般新生代的垃圾回收器会用复制算法)
      在这里插入图片描述

3. JVM中的分代回收

在java8时,堆被分为了两份:新生代和老年代(数量1:2)
对于新生代,内部又被分为了三个区域。

  • 伊甸园区Eden,新生的对象都分配到这里
  • 幸存者区survivor(分成from和to)
  • Eden区, from区, to区(8: 1: 1)
    在这里插入图片描述

3.1 工作机制

  • 新创建的对象,都会先分配到eden区
  • 当伊甸园内存不足,标记伊甸园与from(现阶段没有)的存活对象
  • 将存活对象采用复制算法复制到 to 中,复制完毕后,伊甸园和 from 内存都得到释放
  • 经过一段时间后伊甸园的内存又出现不足,标记eden区域to区存活的对象,将存活的对象复制到from区
  • 当幸存区对象熬过几次回收(最多15次),晋升到老年代(幸存区内存不足或大对象会导致提前晋升)

3.2 MinorGC、 Mixed GC、 FullGC的区别

STW(Stop-The-World):暂停所有应用程序线程,等待垃圾回收的完成

  • MinorGC【young GC】发生在新生代的垃圾回收,暂停时间短(STW)
  • Mixed GC新生代+老年代部分区域的垃圾回收,G1 收集器特有
  • FulIGC:新生代+老年代完整垃圾回收,暂停时间长(STW),应尽力避免(只有新生代和老年代内存完全不足的时候)

4. 垃圾回收器

在jvm中,实现了多种垃圾收集器,包括:

  • 串行垃圾收集器
  • 并行垃圾收集器
  • CMS(并发)垃圾收集器
  • G1垃圾收集器

4.1 串行垃圾收集器

Serial和Serial Old串行垃圾收集器,是指使用单线程进行垃圾回收,堆内存较小,适合个人电脑

  • Serial 作用于新生代,采用复制算法
  • Serial Old 作用于老年代,采用标记-整理算法
    垃圾回收时,只有一个线程在工作,并且java应用中的所有线程都要暂停(STW),等待垃圾回收的完成。
    在这里插入图片描述

4.2 并行垃圾收集器

Parallel New和Parallel Old是一个并行垃圾回收器,JDK8默认使用此垃圾回收器

  • Parallel New作用于新生代,采用复制算法
  • Parallel Old作用于老年代,采用标记-整理算法
    垃圾回收时,多个线程在工作,并且java应用中的所有线程都要暂停(STW),等待垃圾回收的完成。
    在这里插入图片描述

4.3 CMS(并发)垃圾收集器

CMS全称 Concurrent Mark Sweep,是一款并发的、使用标记-清除算法的垃圾回收器,该回收器是针对老年代垃圾回收的,是一款以获取最短回收停顿时间为目标的收集器,停顿时间短,用户体验就好。其最大特点是在进行垃圾回收时,应用仍然能正常运行。
在这里插入图片描述

初始标记是GC Roots连接的,并发标记是下面所有的节点。
重新标记(像检查是否有错题)是检测是否有新连接的或有新垃圾节点出现。
在这里插入图片描述

4.4 G1垃圾收集器

应用于新生代和老年代,在JDK9之后默认使用G1

  • 应用于新生代和老年代,在JDK9之后默认使用G1
  • 划分成多个区域,每个区域都可以充当 eden,survivor, old,humongous(其中 humongous 专为大对象准备)
  • 采用复制算法
  • 响应时间与吞吐量兼顾
  • 分成三个阶段:新生代回收、并发标记、混合收集
  • 如果并发失败(即回收速度赶不上创建新对象速度),会触发 Full GC
    在这里插入图片描述

4.4.1 Young Collection(年轻代垃圾回收)

  • 随着时间流逝,伊甸园的内存又有不足
  • 将伊甸园以及之前幸存区中的存活对象,采用复制算法,复制到新的幸存区,其中较老对象晋升至老年代
    在这里插入图片描述

4.4.2 Young Collection + Concurrent Mark(年轻代垃圾回收+并发标记)

当老年代占用内存超过阈值(默认是45%)后,触发并发标记,这时无需暂停用户线程
在这里插入图片描述

  • 并发标记之后,会有重新标记阶段解决漏标问题,此时需要暂停用户线程。
  • 这些都完成后就知道了老年代有哪些存活对象,随后进入混合收集阶段。此时不会对所有老年代区域进行回收,而是根据暂停时间目标优先回收价值高(存活对象少)的区域(这也是 Gabage First 名称的由来)

4.4.3 Mixed Collection(混合垃圾回收)

混合收集阶段中,参与复制的有 eden、survivor、old
在这里插入图片描述

复制完成,内存得到释放。进入下一轮的新生代回收、并发标记、混合收集

5. 强引用、软引用、弱引用、虚引用的区别

5.1 强引用

只有所有 GC Roots 对象都不通过【强引用】引用该对象,该对象才能被垃圾回收
内存溢出OOM也不会垃圾回收强引用的对象。

String user = new User();

在这里插入图片描述

5.2 软引用

仅有软引用引用该对象时,在垃圾回收后,内存仍不足时会再次出发垃圾回收

User user = new User();
SoftReference softReference = new SoftReference (user);

在这里插入图片描述

5.3 弱引用

仅有弱引用引用该对象时,在垃圾回收时,无论内存是否充足,都会回收弱引用对象

User user = new User);
WeakReference weakReference = new WeakReference(user);

在这里插入图片描述

5.4 虚引用

必须配合引用队列使用,被引用对象回收时,会将虚引用入队,由 Reference Handler 线程调用虚引用相关方法释放直接内存

User user = new User();
ReferenceQueue referenceQueue = new ReferenceQueue();
PhantomReference phantomReference = new PhantomReference (user, queue);

在这里插入图片描述

除了释放user对象,还要释放虚引用对象所关联的一些外部资源——可能是一些外部资源(不是java占用的、也不是java内存,可能是直接内存等…),这些等java对象被回收掉后再释放。所以要把虚拟对象先记录在引用队列中,先记住被回收的对象,后面直接找队列就可以了(释放的时候有专门的线程:Reference Handler)

  • 软引用和弱引用也可以通过引用队列释放相关资源

5.5 区别

  • 强引用:只要所有 GC Roots 能找到,就不会被回收
  • 软引用:需要配合SofiReference使用,当垃圾多次回收,内存依然不够的时候会回收软引用对象
  • 弱引用:需要配合WeakReference使用,只要进行了垃圾回收,就会把弱引用对象回收
  • 虚引用:必须配合引用队列使用,被引用对象回收时,会将虚引用入队,由 Reference Handler 线程调用虚引用相关方法释放直接内存

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

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

相关文章

计算机视觉算法实战——老虎个体识别(主页有源码)

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​ ​​​ 1. 领域介绍 老虎个体识别是计算机视觉中的一个重要应用领域,旨在通过分析老虎的独特条纹图案,自动识别和区…

[Kubernetes] 7控制平面组件

1. 调度 kube- scheduler what 负责分配调度pod到集群节点监听kube-apiserver,查询未分配node的pod根据调度策略分配这些pod(更新pod的nodename)需要考虑的因素: 公平调度,资源有效利用,QoS,affinity, an…

AI赋能Python零代码编程知识技能体系构架

欢迎大家订阅本专栏,下面我先介绍一下本专栏模块结构与知识技能体系。 以下是为您设计的《AI赋能Python零代码编程》专栏目录框架及内容建议,每个方向均包含系列文章规划: 模块一:开发环境搭建 手把手搭建Python全栈开发环境 A…

基于AMD AU15P FPGA的SLVS-EC桥PCIe设计方案分享

作者:Hello,Panda 各位FPGAer周末愉快,今天熊猫君分享一个基于AMD AU15P FPGA的SLVS-EC桥PCIe设计方案。 一、方案背景 先说方案的应用背景:众所周知,较为上层的如基于AI的机器视觉应用,大多基于高端的专用SoC、AI专…

二叉树-二叉树的右视图

二叉树的右视图 给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。输入:二叉树的根结点 输出:整型列表 思路:使用层序遍历,建立二元列…

【C++】vector(下):vector类的模拟实现(含迭代器失效问题)

文章目录 前言一、vector类的常用接口的模拟实现1.头文件(my vector.h)整体框架2.模拟实现vector类对象的常见构造3.模拟实现vector iterator4.模拟实现vector类对象的容量操作5.模拟实现vector类对象的访问6.模拟实现vector类对象的修改操作 二、vector…

抽奖系统测试报告

项目链接: 管理员登录页面 项目功能: 管理员登录: 登录方式分为两种: 手机号密码登录: 正确输入密码和手机号登录 短信验证码登录: 输入手机号,等待验证码,输入验证码登录 管理员注册: 登录页面点击注册按钮即可注册管理员身份 人员管理模块: 人员管理模块分为注册…

理解梯度下降、链式法则、梯度消失/爆炸

第一章:人工智能之不同数据类型及其特点梳理 第二章:自然语言处理(NLP):文本向量化从文字到数字的原理 第三章:循环神经网络RNN:理解 RNN的工作机制与应用场景(附代码) 第四章:循环神经网络RNN、LSTM以及GR…

从零开始用react + tailwindcss + express + mongodb实现一个聊天程序(十一) 实现服务端和客户端socketio 连接

1.后端部分 socketIO文档参考Socket.IO 首先在lib下新建socket.js文件 参考服务器API | Socket.IO import {Server} from socket.io; import http from http import express from "express"const app express() const server http.createServer(app) const io …

Spring Boot使用JDBC /JPA访问达梦数据库

Spring Boot 是一个广泛使用的 Java 框架,用于快速构建基于 Spring 的应用程序。对于达梦数据库(DMDB)的支持,Spring Boot 本身并没有直接内置对达梦数据库的集成,但你可以通过一些配置和依赖来支持达梦数据库。 以下…

蓝桥杯嵌入式学习日记(三)——按键的长按、短按与双击(三行按键法)【STM32】【HAL库】

目录 一、查阅相关资料二、程序的编写1、创建工程2、三行按键法3、短按与长按4、双击 一、查阅相关资料 想要进行一块板子的开发,需要先查阅资料了解器件连接。   从CT117E-M4产品手册中不难发现,按键分别有PB0、PB1、PB2、PA0分别对应B1、B2、B3、B4…

【网络安全 | 漏洞挖掘】通过JWT的IDOR实现账户接管

未经许可,不得转载。 文章目录 正文正文 在审查目标平台“redirect.com”的Web应用时,我发现它使用了JSON Web Token(JWT)进行身份验证,因此决定尝试进行账户接管(ATO)攻击。 首先,我创建了一个新账户并测试了其功能。在此过程中,我尝试在“firstName”字段输入XSS(…

从0到1入门RabbitMQ

一、同步调用 优势:时效性强,等待到结果后才返回 缺点: 拓展性差性能下降级联失败问题 二、异步调用 优势: 耦合度低,拓展性强异步调用,无需等待,性能好故障隔离,下游服务故障不影响…

CST直角反射器 --- 距离多普勒(RD图), 毫米波汽车雷达ADAS

之前几期介绍了雷达是如何从频域换去时域,然后时域计算距离。 这期我们加上一个维度,既看距离,又看速度。速度的计算当然就是多普勒原理,所以距离速度的二维图又叫range-doppler图。 启用雷达ADAS Range-Doppler模板&#xff1a…

手写一个Tomcat

Tomcat 是一个广泛使用的开源 Java Servlet 容器,用于运行 Java Web 应用程序。虽然 Tomcat 本身功能强大且复杂,但通过手写一个简易版的 Tomcat,我们可以更好地理解其核心工作原理。本文将带你一步步实现一个简易版的 Tomcat,并深…

【从零开始学习计算机科学】计算机组成原理(六)异常事件处理

【从零开始学习计算机科学】计算机组成原理(六)异常事件处理 异常事件处理异常处理的数据通路异常事件入口地址 异常事件处理 异常和中断事件改变处理机正常指令的执行顺序。异常指令执行过程中,由于操作非法和指令非法引起的事件。陷阱指陷…

3.3.2 Proteus第一个仿真图

文章目录 文章介绍0 效果图1 新建“点灯”项目2 添加元器件3 元器件布局接线4 补充 文章介绍 本文介绍:使用Proteus仿真软件画第一个仿真图 0 效果图 1 新建“点灯”项目 修改项目名称和路径,之后一直点“下一步”直到完成 2 添加元器件 点击元…

高效运行 QwQ-32B + 错误修复

文章目录 QwQ-32B 错误修复⚙️ 官方推荐设置👍 推荐的 llama.cpp 设置📖 教程:运行和修复的 QwQ-32B1、对于 llama.cpp 及使用 llama.cpp 的引擎:2、下载模型 测试3、测试/评估4、尝试不使用我们的修复方案: &#x…

R 语言科研绘图 --- 直方图-汇总

在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…

1.5.1 掌握Scala内建控制结构 - 条件表达式

本文介绍了 Scala 中条件表达式的使用及其在实际任务中的应用。条件表达式的语法为 if (条件) 值1 else 值2,其结果类型取决于值1和值2的类型。如果类型相同,结果类型与它们相同;如果不同,则结果类型为 Any。通过两个任务展示了条…