JVM垃圾收集器相关面试题(1)
垃圾收集与内存管理摘要
一.核心垃圾收集算法对比
| 算法 | 原理 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 标记-清除 | 两次遍历(标记存活对象→清除未标记对象) | 实现简单 | 内存碎片化、双遍历效率低 | 老年代(结合整理) |
| 标记-复制 | 内存对半分,存活对象复制到空白区 | 无碎片、效率高 | 内存利用率50% | 新生代 |
| 标记-整理 | 标记后移动存活对象至内存端 | 无碎片、内存利用率高 | 对象移动开销大 | 老年代 |
二.分代收集核心机制
内存分代结构
-
新生代(1/3堆)
- Eden区:80%空间,新对象初始分配区,通过连续内存分配优化短命对象处理
- Survivor区:From/To各10%,存放至少存活一次的对象,采用复制算法
-
老年代(2/3堆):存放长周期对象,采用标记-清除/整理算法
-
元空间(本地内存):类元数据存储,GC条件更宽松
回收流程关键点
-
Minor GC(新生代)
- 触发条件:Eden区满
- 对象晋升:年龄阈值(15)或Survivor空间不足
- 复制效率:仅处理存活对象,存活率<10%时最优
-
Full GC(全局)
- 触发条件:老年代不足/显式调用
- 性能影响:全堆扫描,停顿时间显著
三.永久代演进对比
| 特性 | Java7永久代 | Java8+元空间 |
|---|---|---|
| 存储位置 | 堆内存 | 本地内存 |
| GC触发条件 | 类+类加载器+反射引用全解除 | 类加载器回收即释放 |
| 内存管理 | 固定大小易OOM | 动态扩展 |
| 性能影响 | Full GC时扫描 | 独立回收机制 |
四.对象存活判定
- 可达性分析法:通过GC Roots(栈变量、静态属性、JNI引用)遍历引用链
- 死亡判定流程:两次标记机制(可达性分析→finalize()自救机会→不可达回收)
关键设计理念:基于对象生命周期特征(98%对象朝生夕死)进行分代优化,通过空间换时间(复制算法)和延迟处理(老年代整理)平衡吞吐量与停顿时间。
正文
一.常见的垃圾收集算法
标记-清楚
原理:
-
标记:从GC Roots(例如栈中的变量,静态变量等)开始便利,标记出所有被引用的对象
-
清除:遍历整个堆,清除没被标记的对象。
缺点
- 标记和清除各遍历一次,效率低下
- 可能产生大量不连续的空间,当程序需要分配较大内存时,可能会因为无法找到连续的内存空间导致内存不足,从而提前触发垃圾回收。
标记-复制
原理:将内存空间化为等大的两块,一般称为(Form和To空间)。每次只是用其中的一块,当这一块用满后,就将存活的对象复制到另一块空间,然后把原来使用的空间直接清理掉。
优点:
- 只需要复制存活的对象效率很高
- 清除后的空间是连续的
缺点
- 内存空间只占用一般,另一半用来存放复制后的内存,空间浪费严重
标记-整理
原理:
- 标记:与标记-清除算法相同,从GC Root开始遍历所有存活的对象
- 整理:将存活对象向内存的一端移动,此过程不会清除垃圾对象,而是会把存活对象直接挪到垃圾对象,类似于赋值操作,然后直接清理掉边界以外的内存空间。
优点
- 解决了标记-清除算法需要遍历两次和会产生内存碎片的问题,同时也不会和标记-整理算法一样浪费一半的空间
缺点
- 整理过程需要移动对象,效率相对较低,尤其是对象过多的情况下
分代收集
原理
-
基于对象存活周期不同,讲内存化为不同的代
-
新生代:对象通常“朝生夕死”存活率低。一般采用标记-复制算法
-
老生代:对象通常存活率高,占用空间大。一般采用标记-清除或标记-整理算法
优点
- 根据对象存活特点采用不同算法,提高垃圾回收效率,减少对应用程序性能的影响。
缺点
- 需要对堆内存进行分代管理,增加了垃圾回收器的实现复杂度。
二.分代垃圾回收器工作原理详解
分代垃圾回收器是基于一个假说:大部分对象生命周期极短,少数对象长期存活。
堆内存分代结构
-
新生代
-
占堆内存的1/3
-
分为Eden区(80%)和两个Survivor区(From+To 各10%)
- 为什么要有Eden区?直接和正常的标记-复制算法一样不好吗?只要From和To两个分区
- 因为大多数内存活不过一次GC,新对象直接在连续内存的 Eden 区分配,避免频繁内存整理。集中处理 “朝生暮死” 的对象,减少对 Survivor 区的频繁操作。
如果只是用From和To两个Survivor区域,则无法隔离新对象和多次存活对象,导致每次 GC 需扫描全部区域,效率降低。
所以我们再Survivor中存放的是至少存货过一次的对象,Eden区只存放新对象
-
新对象优先在Eden区分配,若Eden区空间不足,则出发Minor GC
-
-
老生代
- 占堆内存2/3,存放长期存活的对象
- 当老生代空间不足时,则出发Full GC或Major GC,回收整个堆
-
元空间
- 取代永久代,存放类元数据,常量池等,GC主要针对不在使用的类的加载器和常量池
对象分配与回收流程
1.对象分配
-
新对象先分配到Eden区,若Eden区已满,则出发Minor GC
-
大对象(如长数组)会直接进入老年代
2.Minor GC(新生代回收)
前面我们总体到Minor GC,那么他到底是个什么呢?
- 存活对象:从 Eden 和 Survivor 区复制到另一个 Survivor 区(复制算法)。
- 对象年龄:每熬过一次 Minor GC,年龄 + 1。
- 晋升老年代:年龄达到阈值(默认 15)或 Survivor 区空间不足时晋升
3.Full GC(老年代回收):
-
触发条件:老年代空间不足、显式调用System.gc()等。
-
使用标记 - 清除或标记 - 整理算法,回收整个堆,耗时长
三.JVM 永久代中会发生垃圾回收吗
-
Java8前 永久代
- 存储位置:JVM堆内存
- GC 条件:类需满足:所有实例被回收 + 类加载器被回收 + 无反射引用。
- 问题:容易因类加载过多引发` ```rustOutOfMemoryError: PermGen space````
-
Java8+ 元空间
-
存储位置:本地内存,不再占用堆。
-
GC 条件:仅需类加载器被回收,自动释放类元数据。
-
改进:
- 内存动态扩展,内存取决于物理内存大小
- 减少 OOM 风险,GC 效率更高。
-
四.如何判断对象是否存活?
可达性算法
-
原理: 从CG Roots出发,遍历所有的引用链,无法到达的对象即为死亡
-
GC Roots 包括:
- 虚拟机栈中局部变量引用的对象。
- 方法区中静态变量和常量引用的对象。
- 本地方法栈中 JNI (Java Native Interface)引用的对象
相关文章:
JVM垃圾收集器相关面试题(1)
垃圾收集与内存管理摘要 一.核心垃圾收集算法对比 算法原理优点缺点适用场景标记-清除两次遍历(标记存活对象→清除未标记对象)实现简单内存碎片化、双遍历效率低老年代(结合整理)标记-复制内存对半分,存活对象复制到…...
详解SQL数据查询功能
数据查询 一、 单表查询1. 选择表中的若干列2. 选择表中的若干元组3. ORDER BY 子句4. 聚合函数5. GROUP BY 子句6. LIMIT 子句综合示例: 二、 多表查询1. 等值连接查询 (Equi-Join)2. 非等值连接查询 (Non-Equi Join)3. 自然连接查询 (Natural Join)4. 复合条件连接…...
车载以太网测试-11【网络层-ICMP协议】
目录 1 摘要2 ICMP协议帧结构2.1 IP头部2.2 ICMP头部2.3 ICMP数据部分2.4 示例:ICMP回显请求(Ping请求) 3 ICMP协议在车载以太网的应用3.1 为什么需要ICMP?3.1.1 网络连通性测试3.1.2 错误报告3.1.3 网络性能监测3.1.4 路径MTU发现…...
leetcode:728. 自除数(python3解法)
难度:简单 自除数 是指可以被它包含的每一位数整除的数。 例如,128 是一个 自除数 ,因为 128 % 1 0,128 % 2 0,128 % 8 0。 自除数 不允许包含 0 。 给定两个整数 left 和 right ,返回一个列表ÿ…...
【QT】-一文读懂抽象类
抽象类(Abstract Class)是面向对象编程中的一个概念,指的是无法被实例化的类,它通常作为其他类的基类。抽象类的作用是定义一个接口(或约定),让派生类(继承自抽象类的类)来实现具体的功能。 抽象类的特点: 包含纯虚函数(Pure Virtual Function): 抽象类通常包含一…...
vue3-computed计算属性和reactive响应式系统结合使用
1.前言 vue3中使用reactive函数创建一个响应式对象,当对象数据发生变化的时候,依赖这些数据的计算属性和模板会自动的更新。 2.实例 2.1 简写 <template><div><p>用户名: {{ userName }}</p><p>用户名的大写形式: {{ u…...
Dubbo请求调用本地服务
文章目录 前言配置 Dubbo 本地调用方法一:application.yml 中配置方法二:DubboReference 注解中指定 注意个人简介 前言 在微服务架构中,Apache Dubbo 作为一款高性能、轻量级的 RPC 框架,被广泛应用于分布式系统。通常ÿ…...
Pycharm 社区版安装教程
找到安装包双击安装文件---点击下一步 一般路径是:C:\Rambo\Software\Development 选择完成后就是如下地址: C:\Rambo\Software\Development\PyCharm Community Edition 2024.3.3 点击上述3个位置就可以了----下一步 等待安装就可以了---完成后点击完成…...
Linux红帽:RHCSA认证知识讲解(六)创建、管理和删除本地用戶和组
Linux红帽:RHCSA认证知识讲解(六)创建、管理和删除本地用戶和组 前言一、用户和组概念用户类型对比表格主要组和补充组对比表格: 二、本地用户账户增删改查三、本地组账户 前言 上篇博客我们详细了解了从红帽和 DNF 软件仓库下载…...
在虚拟环境里面配置Linux系统
Linux系统有很多版本,常用的有Ubantu乌班图,和CentOS 不同的版本在使用的时候,有部分执行方式的不同 安装的流程都一样 首先,想要安装Ubantu,要去它的官网,找下载连接,然后下载iso后缀的安装…...
React开发指南:核心、实践与案例
文章目录 一、React核心架构与设计哲学1.1 虚拟DOM与Diff算法1.2 JSX编译原理1.3 组件化设计模式1.4 Fiber架构解析1.5 组件生命周期(类组件) 二、React核心特性详解2.1 数据流管理2.2 Hooks革命2.3 Context API进阶2.4 自定义Hooks设计模式 三、React 1…...
分享vue好用的pdf 工具实测
vue3-pdf-app: 带大纲,带分页,带缩放,带全屏,带打印,带下载,带旋转 下载依赖: yarn add vue3-pdf-appornpm install vue3-pdf-app 配置类: 创建文件 pdfConfig.ts /…...
Redis分布式锁深度剖析:从原理到Redisson实战,破解脑裂与高并发锁难题
一、📌 分布式锁的核心应用场景 场景类型典型案例风险说明🚀 高并发场景电商秒杀、票务抢购库存超卖风险⏰ 定时任务场景集群日志清理、数据统计任务重复执行🔄 幂等场景支付接口重试、订单创建资金重复扣款 二、🔧 Redis分布式锁…...
Markdown Poster – 免费Markdown转图片工具|优雅图文海报制作与社交媒体分享
Markdown Poster是什么 Markdown Poster 是一款高效的 Markdown 转图片工具,利用灵活编辑和实时预览功能帮助用户轻松制作优雅的图文海报。该工具内置丰富的海报模板和多种主题选项,支持导出为图片和 HTML 代码,适用于社交媒体分享、网站集成…...
掌握市场先机:9款销售渠道管理工具深度测评
本文主要介绍了以下9款销售渠道管理工具:1.纷享销客; 2.销帮帮; 3.小满CRM; 4.有赞; 5.Oracle NetSuite; 6.Salesforce Sales Cloud; 7.Cin7; 8.Pipedrive; 9.BigCommerc…...
OpenCV图像加权函数:addWeighted
1 addWeighted函数 在OpenCV 里,addWeighted 函数的作用是对两个图像进行加权求和,常用于图像融合、图像过渡等场景。函数如下: cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]])2 参数解释 src1:第一个输入图…...
直方图(信息学奥赛一本通-1115)
【题目描述】 给定一个非负整数数组,统计里面每一个数的出现次数。我们只统计到数组里最大的数。假设 Fmax(Fmax<10000)是数组里最大的数,那么我们只统计{0,1,2.....Fmax}里每个数出现的次数。 【输入】 第一行n是数组的大小。…...
docker桌面版启动redis,解决无法连接
docker run -d --name redis -p 6379:6379 -v E:\2\redis\redis.conf:/usr/local/etc/redis/redis.conf redis redis-server /usr/local/etc/redis/redis.conf 在本地创建一个目录,里面有个redis.conf文件,内容如下,启动时绑定这个配置文件目…...
Scratch 3.0安装包,支持Win7/10/11、Mac电脑手机平板、少儿便编程的启蒙软件。
Scratch是一款由麻省理工学院(MIT) 设计开发的少儿编程工具。其特点是:使用者可以不认识英文单词,也可以不使用键盘,就可以进行编程。构成程序的命令和参数通过积木形状的模块来实现。用鼠标拖动指令模块到脚本区就可以…...
Java创造型模式之原型模式详解
设计模式是面向对象设计中的一种标准方法,用于解决常见的设计问题。原型设计模式(Prototype Pattern)是23种经典设计模式之一,属于创建型模式,它允许通过复制现有对象来创建新对象,而不是通过构造函数或工厂…...
JVM的各种细节
(1)JVM 核心结构(必须知道) 类加载器 负责将.class()文件加载到内存中,供 JVM 使用。 方法区 存储类元数据(类名、字段、方法)、常量池、静态变量等。 JDK 8:由元空间(Metaspace)…...
JavaScript基本知识
文章目录 一、JavaScript基础1.变量(重点)1-1 定义变量及赋值1-2 变量的命名规则和命名规范判断数据类型: 2.数据类型转换2-1 其他数据类型转成数值2-2 其他数据类型转成字符串2-3 其他数据类型转成布尔 3.函数3-1函数定义阶段3-2函数调用阶段…...
Navicat for Snowflake 震撼首发,激活数据仓库管理全新动能
近日,Navicat 家族迎来了一位全新成员 — Navicat for Snowflake。Snowflake 是一款基于云架构的现代数据仓库解决方案,以其弹性扩展、高性能和易用性著称。这次首发的Navicat for Snowflake 专为简化 Snowflake 数据库管理任务而精心打造。它凭借其直观…...
pjsip 自定义获取和设置麦克风、扬声器
获取麦克风和扬声器列表结果Device ID: 0 Name: “Wave mapper” Input channels: 2 Output channels: 2 Default sample rate: 16000 Device ID: 1 Name: “麦克风 (USB Microphone)” Input channels: 2 Output channels: 0 Default sample rate: 16000 Device ID: 2 Name: “…...
C++ 左值(lvalue)和右值(rvalue)
在 C 中,左值(lvalue)和右值(rvalue)是指对象的不同类别,区分它们对于理解 C 中的表达式求值和资源管理非常重要,尤其在现代 C 中涉及到移动语义(Move Semantics)和完美转…...
深度学习基础:线性代数本质2——线性组合、张成的空间与基
目录 一、线性组合 1. 用一个有趣的角度看向量坐标 2. 如果我们选择不同的基向量会怎样? 3. 线性组合 4. 张成的空间 ① 二维向量的张成的空间 ② 三维向量的张成的空间编辑 5.线性相关 6.线性无关 7. 基的定义 一、线性组合 1. 用一个有趣的角度看向量坐…...
第五天 Labview数据记录(5.4 EXCEL文件读写)
5.4 EXCEL文件读写 Excel 文件读写在数据处理、自动化办公、数据分析等领域具有重要的意义。以下是 Excel 文件读写的主要应用场景和意义:1. 数据管理和整理;2. 自动化办公;3. 数据分析和可视化;4. 系统集成;5. 报表生…...
iOS 模块化架构设计:主流方案与实现详解
随着 iOS 工程规模的扩大,模块化设计成为提升代码可维护性、团队协作效率和开发灵活性的关键。本文将探讨为什么需要模块化,介绍四种主流的模块化架构方案(协议抽象、依赖注入、路由机制和事件总线),并通过代码示例和对…...
【WRF模拟】如何查看 WPS 的输入静态地理数据(二进制格式)?
查看 WPS 的输入静态地理数据方法总结 方法 1:使用 gdal_translate 将二进制数据转换为 GeoTIFFgdal_translate 工具概述使用 gdal_translate 将二进制数据转换为 GeoTIFF方法 2:使用 ncdump 查看 geo_em.dXX.nc方法 3:使用 Python xarray + matplotlib 可视化 geo_em.dXX.n…...
麒麟系统利用pycharm生成deb文件
在麒麟系统(Kylin OS)上使用 PyCharm 进行 Python 开发并生成 .deb 可安装软件包,可以按照以下步骤进行操作: 1. 准备工作 安装 PyCharm:确保已经在麒麟系统上安装了 PyCharm,可以使用官方提供的安装包进…...
