JVM垃圾回收面试题及原理

news2025/3/13 13:46:56

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 线程调用虚引用相关方法释放直接内存

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

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

相关文章

Flutter 小技巧之通过 MediaQuery 优化 App 性能

许久没更新小技巧系列,温故知新,在两年半前的《 MediaQuery 和 build 优化你不知道的秘密》 我们聊过了在 Flutter 内 MediaQuery 对应 rebuild 机制,由于 MediaQuery 在 MaterialApp 内,并且还是一个 InheritedWidget &#xff0…

SpringBoot基础Kafka示例

这里将生产者和消费者放在一个应用中 使用的Boot3.4.3 引入Kafka依赖 <dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId> </dependency>yml配置 spring:application:name: kafka-1#kafka…

Spring 的三种注入方式?

1. 实例的注入方式 首先来看看 Spring 中的实例该如何注入&#xff0c;总结起来&#xff0c;无非三种&#xff1a; 属性注入 set 方法注入 构造方法注入 我们分别来看下。 1.1 属性注入 属性注入是大家最为常见也是使用最多的一种注入方式了&#xff0c;代码如下&#x…

STM32第一天建立工程

新建一个工程 1&#xff1a;新建一个文件&#xff0c;添加文件 a:DOC工程说明 》doc说明文档 b&#xff1a;Libraries固件库 》cmsis内核文件 &#xff08;一般这就是stm32内核文件&#xff09; 》FWLIB外设文件 &#xff08;这种就是stm32外设文件不全&#xff09; 》start…

搭建本地化笔记AI:用Copilot+deepseek+nomic-embed-text构建本地智能知识系统

安装Ollama https://ollama.com/ 下载模型 下载大语言模型 根据自己电脑的配置选择模型的大小 ollama run deepseek-r1:8b 下载向量处理模型 创建向量数据库时需要使用Embedding模型对文本进行向量化处理 ollama pull nomic-embed-text 查看安装的模型 ollama listNAME …

【蓝桥杯单片机】第十一届省赛

一、真题 二、创建工程 1.在C盘以外的盘新建文件夹&#xff0c;并在文件夹里面创建两个文件夹Driver 和Project 2.打开keil软件&#xff0c;在新建工程并选择刚刚建好的project文件夹&#xff0c;以准考证号命名 3.选择对应的芯片型号 4.选择否&#xff0c;即不创建启动文件 …

【存储中间件】Neo4J图数据库超详细教程(一):相关介绍、特点及优势、数据模型、软件安装

文章目录 Neo4J超详细教程一、Neo4J相关介绍1.为什么需要图数据库方案1&#xff1a;Google方案2&#xff1a;Facebook 2.特点和优势3.什么是Neo4j4.Neo4j数据模型图论基础属性图模型Neo4j的构建元素 5.软件安装 个人主页&#xff1a;道友老李 欢迎加入社区&#xff1a;道友老李…

xxl-job部署在docker-destop,实现定时发送预警信息给指定邮箱

XXL-JOB XXL-JOB是一个分布式任务调度平台&#xff08;XXL是作者徐雪里姓名拼音的首字母&#xff09;&#xff0c;其核心设计目标是开发迅速、学习简单、轻量级、易扩展。 源码仓库地址&#xff1a;https://github.com/xuxueli/xxl-job 源码结构&#xff1a; 系统架构 在xxl-j…

【QT】QScrollBar设置样式:圆角、隐藏箭头、上边距等

目录 0.简介 1.原理 2.具体代码 0.简介 环境&#xff1a;Ubuntu22.04、qtDesigner绘制UI 项目需要&#xff0c;按照UI修改滚动条样式&#xff0c;滚动条我使用的是QScrollBar&#xff0c;默认样式和修改之后的样式如下&#xff1a; 1.原理 2.具体代码 我是用qtDesigner绘制…

trae中文版AI搭建完整可用的项目框架

Trae 是由字节跳动推出的 AI 原生集成开发环境&#xff08;AI IDE&#xff09;&#xff0c;号称可以搭建完整项目&#xff0c;个人试用后体验确实比Cursor或cline更便捷&#xff0c;因为他多个文件关联准确率更高。 正式版的trae不支持大陆使用&#xff0c;不过目前已经推出了…

cfi网络安全 网络安全hcip

目录 RIP (路由信息协议) 算法 开销 版本 开销值的计算方式 RIPV1和RIPV2的区别 RIP的数据包 Request(请求)包 Reponse(应答)包 RIP的特征 周期更新 RIP的计时器 1&#xff0c;周期更新计时器 2&#xff0c;失效计时器 3&#xff0c;垃圾回收计时器 RIP的核心思…

Banana Pi 与瑞萨电子携手共同推动开源创新:BPI-AI2N

2025年3月11日&#xff0c; Banana Pi 开源硬件平台很高兴宣布&#xff0c;与全球知名半导体解决方案供应商瑞萨电子&#xff08;Renesas Electronics&#xff09;正式达成技术合作关系。此次合作标志着双方将在开源技术、嵌入式系统和物联网等领域展开深度合作&#xff0c;为全…

linux 命令 ls

ls 是 Linux 系统中用于列出目录内容的核心命令&#xff0c;几乎所有日常操作都会用到。以下是其详细用法和常见场景说明 1. 基础语法 ls [选项] [目录/文件] 不指定目录时&#xff0c;默认列出当前目录的内容。 可以指定文件或目录路径&#xff0c;支持通配符&#xff08;如…

C#-扩展方法-Linq

密封类 sealed&#xff0c;无法被继承 var 可以定义匿名对象 static void test1() {var t 1;t "jack";//报错&#xff0c;类型已经确定好了var s new{id 1,name "tom"};Console.WriteLine(s.id s.name); } 扩展方法 对现有类型做方法的扩展&am…

Go红队开发—web网络编程

文章目录 web网络编程Req快速请求 调试DevModeDebugLogTraceInfo瓶颈分析 控制请求与响应控制请求的字段内容控制调试打印的内容分开dump请求与响应部分请求体设置 作用范围级别设置参数查询URL 路径参数表单请求设置请求头设置 判断响应状态码解析数据SetSuccessResultgjson响…

轻量级模块化前端框架:快速构建强大的Web界面

轻量级模块化前端框架&#xff1a;快速构建强大的Web界面 在当今快节奏的Web开发环境中&#xff0c;选择一个高效且灵活的前端框架至关重要。UIkit 是一个轻量级的模块化前端框架&#xff0c;旨在帮助开发者快速构建功能强大且响应迅速的Web界面。 UIkit提供了丰富的组件和工…

qt+opengl 播放yuv视频

一、实现效果 二、pro文件 Qt widgets opengl 三、主要代码 #include "glwidget.h"GLWidget::GLWidget(QWidget *parent) : QOpenGLWidget(parent) {connect(&m_timer, &QTimer::timeout, this,[&](){this->update();});m_timer.start(1000/33); }v…

5G基本概念

作者:私语茶馆 1. 5G应用场景概述 1.1.5G应用场景 ITU域2015年定义了三大应用场景:eMBB(增强型移动宽带)、uRLLC(低时延高可靠通信)、mMTC(海量物联网通信); emBB:Enhanced Mobile Broadband ,移动互联网应用,是4G MBB(移动宽带)的升级,主要侧重于网络速率、带…

PH热榜 | 2025-03-12

1. Fluently 标语&#xff1a;开始说英语&#xff0c;就像说你的母语一样流利。 介绍&#xff1a;想象一下&#xff0c;有一个像人类一样的英语教练&#xff0c;全天候在线、价格却便宜15倍。这就是 Fluently &#x1f680; 纠正你的错误&#xff0c;提升你的词汇量、发音和语…

Python Web项目的服务器部署

一.部署运行 1.虚拟环境的安装&#xff1a;&#xff08;一行一行运行&#xff09; wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh bash miniconda.sh -b -p /opt/miniconda3 echo export PATH"/opt/miniconda3/bin:$PAT…