高级java每日一道面试题-2024年10月24日-JVM篇-说一下JVM有哪些垃圾回收器?

如果有遗漏,评论区告诉我进行补充

面试官: 说一下JVM有哪些垃圾回收器?

我回答:

1. Serial收集器

  • 特点:Serial收集器是最古老、最稳定的收集器,它使用单个线程进行垃圾收集工作。在进行垃圾回收时,它会暂停所有用户线程,即Stop The World(STW)。
    • 单线程工作,适合单核 CPU。
    • 在年轻代(Young Generation)中使用,称为 Serial。
    • 在老年代(Old Generation)中使用,称为 Serial Old。
    • 收集速度快,但会暂停整个应用。
    • 适合小型应用或测试环境。
  • 应用场景:适用于单CPU环境或内存较小、对停顿时间要求不高的应用。
  • 回收算法
    • 在新生代,它采用复制算法,将新生代划分为一个 Eden 区和两个 Survivor 区,默认比例是 8:1:1。在垃圾回收时,将 Eden 区和其中一个 Survivor 区中存活的对象复制到另一个 Survivor 区。
    • 在老年代,它采用标记 - 整理算法,对存活对象进行标记后,将其移动到一端,清除另一端的垃圾。

2. ParNew收集器

  • 特点:ParNew收集器是Serial收集器的多线程版本,也被称为“并行年轻代收集器”。它可以与CMS收集器配合使用,以实现更短的停顿时间。
    • 多线程工作,适合多核 CPU。
    • 在年轻代中使用,称为 ParNew 或者 Parallel。
    • 专注于吞吐量优化。
    • 使用复制算法(Copy)或标记-压缩算法(Mark-Compact)。
    • 适合需要高吞吐量的应用。
  • 应用场景:适用于多CPU环境,特别是需要缩短年轻代垃圾回收停顿时间的应用。
  • 回收算法
    • 在新生代采用复制算法,其内存区域划分和 Serial 回收器相同,也是 Eden 区和两个 Survivor 区。

3. Parallel收集器(Parallel Scavenge)

  • 特点:Parallel收集器是一种多线程并行的垃圾收集器,它关注点是吞吐量(运行用户代码时间与CPU总消耗时间的比值)。它同样适用于新生代和老年代的回收。
  • 应用场景:适用于对吞吐量有较高要求的应用,如后台计算任务等。
  • 回收算法
    • 在新生代采用复制算法,通过参数调整可以控制新生代的大小、Survivor 区比例等内存分配策略,以优化吞吐量。

4. CMS(Concurrent Mark-Sweep)收集器

  • 特点:CMS收集器是一种以获取最短回收停顿时间为目标的收集器。它是第一款并发收集器,可以实现垃圾收集线程与用户线程同时工作。但需要注意的是,CMS收集器对CPU资源敏感,且无法处理浮动垃圾,还可能产生大量空间碎片。
    • 并发标记和清扫,减少暂停时间。
    • 专注于降低停顿时间。
    • 使用标记-清除算法(Mark-Sweep)。
    • 可能会产生碎片。
    • 适合对响应时间敏感的应用。
  • 应用场景:适用于对停顿时间有严格要求的应用,如Web服务等。

5. G1(Garbage-First)收集器

  • 特点:G1收集器是一种面向服务端应用的垃圾收集器,它逐步取代了CMS收集器。G1收集器具有更可控的停顿时间和高效的并发能力。它将堆内存划分为多个大小相等的独立区域(Region),并根据对象的存活周期和垃圾回收的优先级来选择要回收的区域。
    • 设计目标是在控制 GC 停顿时间的同时获得高吞吐量。
    • 使用分区(Region)的概念,将堆划分为多个小块。
    • 并发执行,适合大堆(Large Heap)。
    • 自适应调整策略,自动选择最优的收集时机。
    • 适合对停顿时间和吞吐量都有较高要求的应用。
  • 应用场景:适用于对停顿时间和吞吐量都有较高要求的大型应用。
  • 回收过程及算法
    • 初始标记(Initial Mark):需要暂停所有用户线程,标记从 GC Roots 能直接关联到的对象,时间很短。
    • 并发标记(Concurrent Mark):与用户线程并发执行,对堆中对象进行可达性分析,标记存活对象。
    • 最终标记(Final Mark):需要暂停所有用户线程,处理并发标记阶段遗留的少量的 SATB(Snapshot - At - The - Beginning)记录。
    • 筛选回收(Live Data Counting and Evacuation):对各个区域的回收价值和成本进行排序,根据设定的停顿时间,选择部分区域进行回收,回收过程中采用复制算法,将存活对象复制到新的区域。

6. ZGC Collector(Z Garbage Collector)

  • 特点
    • 专注于极低的 GC 停顿时间。
    • 使用并行与并发技术。
    • 适合非常大的堆(数 TB)。
    • 适用于需要极高响应时间的应用。
    • 从 Java 11 开始引入。

7. Shenandoah Collector

  • 特点
    • 类似于 ZGC,专注于极低的 GC 停顿时间。
    • 使用并行与并发技术。
    • 适合需要极高响应时间的应用。
    • 从 Java 9 开始作为实验性功能,Java 12 作为正式功能引入。

8. Parallel Old Collector

  • 特点
    • 与 Parallel Collector 配合使用。
    • 在老年代中使用,称为 Parallel Old。
    • 适用于需要高吞吐量的应用。
  • 回收算法
    • 采用标记 - 整理算法进行老年代垃圾回收。

9. Serial Old Collector

  • 特点

    • 与 Serial Collector 配合使用。
    • 在老年代中使用,称为 Serial Old。
    • 适用于小型应用或测试环境。
  • 适用场景

    • 主要用于 Client 模式下的老年代垃圾回收,或者在 Server 模式下与 Parallel Scavenge 回收器搭配使用,用于处理 CMS 回收器产生的垃圾碎片等情况。
  • 回收算法

    • 采用标记 - 整理算法进行老年代垃圾回收。

10. Concurrent Mark Sweep Collector (CMS)

  • 特点
    • 已经在 Java 9 中被标记为废弃,并在 Java 14 中被移除。
    • 曾经用于降低停顿时间,但在现代 JVM 中已经被 G1 等更先进的收集器取代。
  • 回收过程及算法
    • 初始标记(Initial Mark):需要暂停所有用户线程,标记从 GC Roots 能直接关联到的对象,速度很快。
    • 并发标记(Concurrent Mark):可以与用户线程并发执行,从初始标记的对象开始,遍历整个老年代,标记所有存活的对象。
    • 重新标记(Remark):需要暂停所有用户线程,修正并发标记期间因用户线程继续运行而导致标记变动的那部分对象的标记记录,这个阶段的停顿时间比初始标记长,但远比并发标记短。
    • 并发清除(Concurrent Sweep):与用户线程并发执行,清除未被标记的垃圾对象。
    • 整体采用标记 - 清除算法,在并发清除阶段会产生一定的内存碎片。

垃圾回收算法简介

为了更好地理解垃圾回收器的工作原理,以下是几种常见的垃圾回收算法的简要介绍:

  • 标记-清除算法:该算法分为标记和清除两个阶段。在标记阶段,垃圾回收器会从GC Roots开始遍历所有可达的对象,并标记它们为活动对象。在清除阶段,垃圾回收器会遍历整个堆,回收所有未被标记的对象的内存。但这种方法可能会产生大量不连续的内存碎片。
  • 标记-整理算法:该算法是标记-清除算法的改进版本。它在标记和清除的基础上增加了整理阶段,将所有活动对象向一端移动,从而消除内存碎片。但这种方法可能会增加额外的开销。
  • 复制算法:该算法通常用于新生代垃圾回收。它将内存分为Eden空间和两个Survivor空间。在垃圾回收时,将还存活的对象复制到另一个Survivor空间或老年代中,然后清空当前使用的空间。这种方法可以减少内存碎片的产生,但可能会浪费一定的空间。

总结

选择合适的垃圾回收器需要根据应用程序的具体需求和运行环境进行权衡。以下是一些选择垃圾回收器时需要考虑的因素:

  • 内存大小:对于大内存应用,G1和CMS可能是更好的选择。
  • 吞吐量:如果对吞吐量有较高要求,Parallel GC是较好的选择。
  • 停顿时间:对于对响应时间要求较高的应用,CMS和G1可能更合适。
  • CPU资源:并行和并发垃圾收集器会占用额外的CPU资源来进行垃圾回收工作。如果应用程序本身已经对CPU资源有较高的需求,那么需要谨慎选择垃圾收集器,以避免对应用程序性能造成过大影响。
  • 垃圾产生速度:如果应用程序产生垃圾的速度非常快,那么需要选择能够高效处理大量垃圾的收集器,如G1或Parallel GC。
  • JVM版本:不同版本的JVM可能支持不同的垃圾收集器,且同一收集器在不同版本中的表现也可能有所不同。因此,在选择垃圾收集器时,还需要考虑JVM的版本兼容性。

垃圾收集器的调优是一个复杂的过程,需要根据具体的应用场景和性能目标进行调整。以下是一些常见的调优策略:

  • 设置合适的堆内存大小:堆内存设置过大或过小都会影响垃圾收集器的性能。过大可能导致垃圾回收时间过长,过小则可能频繁触发垃圾回收。因此,需要根据应用程序的内存需求来设置合适的堆内存大小。

JVM的垃圾回收器有多种类型,每种类型都有其特定的应用场景和优势。在选择垃圾回收器时,需要根据应用的特点和需求进行权衡和选择。同时,了解垃圾回收算法的基本原理也有助于更好地理解垃圾回收器的工作原理和优化策略。

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

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

相关文章

【每日一题】LeetCode - 整数转罗马数字

在罗马数字系统中,七个不同的符号代表不同的值: 符号值I1V5X10L50C100D500M1000 罗马数字的表示方式是从最大值开始逐次减去每个符号的值,通过组合这些符号构建最终的表示形式。本文将介绍一个基于贪心策略的解决方案,将整数转换…

unity开发之Line Renderer

Line Renderer 是一个有用的工具,可让您在游戏中绘制线条。 它可以用作游戏的函数或调试标记。 在这里,让我们创建一个程序,根据基本用法在 Line Renderer 上移动。 目录 如何使用 Line Renderer 和基础知识 在场景中放置 Line Renderer关键组…

音视频同步版本【基于音频】

其实和基于外部时钟的原理操作基本上一模一样。只不过音频帧不需要去匹配现实时钟了,只有视频帧需要匹配现实时钟。而视频帧需要去匹配音频帧的时间,那么就需要给时钟设置一个补偿,因为现在是以音频帧为标准。假如现在现实时钟到了50pts&…

Catalan数 C++解决

输入描述 输入一个正整数n。 输出描述 输出Catalan数的前n项。 用例输入 1 0 用例输出 1 1 用例输入 2 5 用例输出 2 1 1 2 5 14 42 #include<bits/stdc.h> using namespace std; int main() {int n;cin>>n;int dp[n1]{0};dp[0]dp[1]1;for(int m2;…

守护头顶安全——AI高空抛物监测,让悲剧不再重演

在城市的喧嚣中&#xff0c;我们享受着高楼林立带来的便捷与繁华&#xff0c;却往往忽视了那些隐藏在高空中的危险。近日&#xff0c;震惊全国的高空抛物死刑案件被最高院核准并执行。案件中被告人多次高空抛物的举动&#xff0c;夺去了无辜者的生命&#xff0c;也让自己付出了…

项目集群部署定时任务重复执行......怎么解决???

项目集群部署在不同服务器&#xff0c;导致定时任务重复执行 1、可以在部署时只让一个服务器上有定时任务模块&#xff0c;不过这样如果这台服务器宕机&#xff0c;就会导致整个定时任务崩溃 2、使用分布式锁&#xff0c;使用redis setNX命令加lua脚本在定时任务执行的时候只…

Go 语言中的 for range 循环教程

在 Go 语言中&#xff0c;for range 循环是一个方便的语法结构&#xff0c;用于遍历数组、切片、映射和字符串。本教程将通过示例代码来帮助理解如何在 Go 中使用 for range 循环。 package mainimport "fmt"func main() {// 遍历切片并计算和nums : []int{2, 3, 4}…

Kafka-代码示例

一、构建开发环境 File > New > Project 选择一个最简单的模板 项目和坐标命名 配置maven路径 添加maven依赖 <dependencies><!-- https://mvnrepository.com/artifact/org.apache.kafka/kafka-clients --><dependency><groupId>org.apache.kaf…

深度学习 基本函数01

np.dot 是 NumPy 库中的一个函数&#xff0c;用于计算两个数组的点积&#xff08;也称为内积或数量积&#xff09;。点积是两个向量的对应元素乘积之和。 np.random.normal 是 NumPy 库中的一个函数&#xff0c;用于生成符合正态分布&#xff08;也称为高斯分布&#xff09;的…

项目管理软件中这6个小技巧帮助项目经理同时管理多个项目

在网上看到一个数据&#xff0c;只有15%的项目经理一次只需要负责一个项目&#xff0c;其他的项目经理都需要同时负责多个项目&#xff0c;甚至有15%的项目经理一次需要负责10个以上的项目。 我在工作中&#xff0c;也只有很少很少的时间里&#xff0c;是一次性只负责一个项目…

目标检测——yolov5-3.1的环境搭建和运行

第一步&#xff1a;安装anaconda环境&#xff0c;并且配置好cuda&#xff0c;安装需要的基本包 查看对应cuda版本&#xff0c;后续下载cudatoolkit需要对应版本 nvcc -V 第二步&#xff1a;创建虚拟环境&#xff0c;激活环境&#xff0c;安装所需的包 conda create -n yolo…

Spark实现PageRank算法

详细步骤&#xff1a; 1、创建Spark sql 环境 2、读取数据 3、数据切分 &#xff08;分为page列&#xff0c;outLink列&#xff09;形成表 pageDF 4、新增pr一列 (给定初始值) 形成表 initPrDF 5、新增avgPr一列&#xff08;根据出链关系&#xff0c;求每个页面所分到…

Visual studio 下载安装

1&#xff0c;Visual stutdio 网址 下载 Visual Studio Tools - 免费安装 Windows、Mac、Linux 2&#xff0c;下划页面&#xff0c;点击 较早的下载 3&#xff0c;选择对应的版本进行下载

《深度学习》YOLO v1网络架构 、损失值、NMS极大值抑制

目录 一、Yolo系列v1 1、核心思想 2、示例 3、流程图解析 二、YOLO系列v1损失函数 1、位置误差 2、置信度误差 3、类别概率损失 三、NMS非极大值抑制 1、概念 2、步骤 四、YOLO v1优缺点 1、优点 1&#xff09;速度快 2&#xff09;端到端 3&#xff09;多尺度…

docker 可用镜像服务地址(2024.10.25亲测可用)

1.错误 Error response from daemon: Get “https://registry-1.docker.io/v2/” 原因&#xff1a;镜像服务器地址不可用。 2.可用地址 编辑daemon.json&#xff1a; vi /etc/docker/daemon.json内容修改如下&#xff1a; {"registry-mirrors": ["https://…

Python爬虫:从入门到精通

Python爬虫&#xff1a;从入门到精通 在数字时代&#xff0c;信息就如同水源&#xff0c;源源不绝。然而&#xff0c;当你想要从海量的信息中汲取有价值的“水”&#xff0c;你会发现这并不是一件容易的事。这就是为什么网络爬虫出现了。它们帮助我们在网络的海洋中航行&#…

光伏业务管理软件:提升企业管理效率的利器

一、优化业务流程 光伏业务管理软件能够对企业的各项业务流程进行全面梳理和优化。从项目前期的规划设计、设备采购&#xff0c;到项目建设中的施工管理、质量控制&#xff0c;再到项目后期的运维服务&#xff0c;软件都可以进行有效的跟踪和管理。 通过规范业务流程&#xf…

力扣第23题:合并K个升序链表

详解力扣第23题&#xff1a;合并K个升序链表 题目描述 给你一个链表数组&#xff0c;每个链表都已经按升序排列。请你将所有链表合并到一个升序链表中&#xff0c;返回合并后的链表。 本题可以通过优先队列-最小堆来高效解决&#xff0c;因为我们需要频繁地找到当前K个链表中…

银行客户贷款行为数据挖掘与分析

#1024程序员节 | 征文# 在新时代下&#xff0c;消费者的需求结构、内容与方式发生巨大改变&#xff0c;企业要想获取更多竞争优势&#xff0c;需要借助大数据技术持续创新。本文分析了传统商业银行面临的挑战&#xff0c;并基于knn、逻辑回归、人工神经网络三种算法&#xff0…

2024 10.25 判断一个矩阵是否对称

主对角线对称 思路&#xff1a;a[i][j]!a[j][i] 第一行和第一列顺序比较&#xff0c;后面依次类推 #include <stdio.h>int main(){int n,m;scanf("%d",&n);int a[n][n];for(int i0;i<n;i){for(int j0;j<n;j)scanf("%d",&a[i][j]);}i…