JVM垃圾收集器合集

news2025/3/13 16:47:48

前言:JVM GC收集器的回顾与比较

JVM(Java虚拟机)中的垃圾收集器是自动管理内存的重要机制,旨在回收不再使用的对象所占用的内存空间。以下是JVM中几种常见的垃圾收集器的详细介绍:

一、新生代垃圾收集器

  1. 1.Serial收集器
    • 类型:单线程收集器,新生代。
    • 特点:在垃圾收集时,会暂停所有其他工作线程(Stop-The-World),简单高效,发展历史最悠久。
    • 适用场景:适用于单核处理器环境和Client模式下的虚拟机。
‌Serial收集器是Java虚拟机(JVM)中最基本、历史最悠久的垃圾收集器之一‌。
它是一个单线程的垃圾收集器,这意味着它只会使用一个线程来完成垃圾收集工作。
Serial收集器在进行垃圾收集时,必须暂停其他所有的工作线程
(称为“Stop The World”,简称STW),直到垃圾收集结束。
这种设计虽然简单高效,但会导致应用在垃圾收集期间完全停顿,影响用户体验‌

使用场景
Serial收集器主要用于客户端模式下的应用。由于客户端应用的内存通常较小,垃圾收集的时间较短,
只要不频繁发生停顿,这种设计是可以接受的。
此外,Serial收集器也是JDK 1.7及以前版本中Client模式下的默认新生代收集器‌

优缺点
‌优点‌:

‌简单高效‌:由于没有线程交互的开销,Serial收集器在单线程环境下可以获得较高的收集效率。
资源消耗少‌:对于限定单个CPU的环境来说,Serial收集器由于没有线程交互的开销,
专心做垃圾收集自然可以获得最高的单线程收集效率‌

‌缺点‌:
‌停顿时间长‌:在进行垃圾收集时,必须暂停所有其他工作线程,导致应用完全停顿,影响用户体验‌
‌不适用于多核环境‌:在多核环境下,由于只有一个线程工作,无法充分利用多核处理器的优势‌
  1. 2.ParNew收集器
    • 类型:多线程收集器,新生代。
    • 特点:ParNew收集器是Serial收集器的多线程版本,除了使用多线程进行垃圾收集外,其余行为与Serial收集器相同。
    • 适用场景:适用于多核处理器环境。
‌ParNew是Java虚拟机(JVM)中的一个年轻代垃圾回收器,它是Serial收集器的多线程版本‌。
ParNew主要用于客户端应用或对响应时间敏感的应用程序,能够在多核处理器上发挥优势,
通过多线程并行处理垃圾回收工作,从而缩短Stop-The-World(STW)时间‌

工作原理
ParNew的主要工作原理包括以下几点:
‌并行性‌:ParNew使用多线程同时执行垃圾收集工作,
这使得它能够在多核处理器上发挥优势,缩短STW时间‌
‌分代收集‌:ParNew只关注年轻代的垃圾回收,不处理老年代的垃圾回收。
当年轻代空间不足时,ParNew会被触发‌
‌复制算法‌:在年轻代中采用复制算法,将年轻代分为Eden区和两个Survivor区(S0和S1)。
垃圾收集时,所有存活的对象会被复制到另一个Survivor区或老年代,原来的Survivor区则被清空‌
‌对象晋升‌:经过几次垃圾回收后,存活的对象会被晋升到老年代,以减少年轻代的垃圾回收频率‌

适用场景和优缺点
ParNew适用于以下场景:

‌响应时间敏感的应用程序‌:由于ParNew的多线程特性,它能够在短时间内完成垃圾回收,
减少STW时间,适合交互式应用程序‌
‌服务器端大型系统‌:在多核CPU服务器上,ParNew能够充分发挥硬件优势,
提升回收效率,适用于高并发场景‌

然而,ParNew也有一些局限性:
‌仅限于年轻代‌:ParNew不适用于整个堆的垃圾收集,只专注于年轻代‌
‌不适合高吞吐量应用‌:对于需要最大化CPU利用率的应用程序,ParNew可能不是最佳选择,
因为它的STW时间虽然较短,但总的垃圾收集时间可能较长‌
  1. 3.Parallel Scavenge收集器
    • 类型:多线程收集器,新生代。
    • 特点:追求高吞吐量,即CPU用于运行用户代码的时间与CPU总消耗时间的比值高。停顿时间越短越适合需要与用户交互的程序,而高吞吐量则可用高效率地利用CPU时间,尽快完成程序的运算任务。
    • 适用场景:主要适合在后台运算而不需要太多交互的任务。
‌Parallel Scavenge收集器是JVM(Java虚拟机)中的一个垃圾收集器,主要用于新生代垃圾收集,
采用标记-复制算法。‌

Parallel Scavenge收集器是一款新生代收集器,主要关注垃圾收集的吞吐量。
吞吐量是指在一定时间内成功完成的工作量或任务的数量,即用户线程运行时间占总时间的比例。
Parallel Scavenge收集器通过多线程并行执行垃圾回收操作,提高吞吐量‌

Parallel Scavenge收集器的特点
‌并行处理‌:Parallel Scavenge收集器可以并行处理垃圾回收任务,利用多线程提高垃圾收集的效率。
‌关注吞吐量‌:其主要目标是优化系统的整体吞吐量,减少垃圾收集对系统性能的影响。
‌参数调节‌:提供了-XX:MaxGCPauseMillis参数,用于控制最大垃圾回收停顿时间,
通过牺牲部分吞吐量来减少停顿时间‌

Parallel Scavenge收集器的使用场景
Parallel Scavenge收集器适合那些对实时性要求不高,但需要高吞吐量的应用场景。
例如,科学数据计算、批量处理任务等。在这些场景下,虽然垃圾收集会占用一定的时间,
但总体上可以提高系统的处理效率‌

二、老年代垃圾收集器

  1. 1.Serial Old收集器
    • 类型:单线程收集器,老年代。
    • 特点:Serial Old是Serial收集器的老年代版本,使用标记整理算法。
    • 适用场景:适用于单核处理器环境和Client模式下的虚拟机。
‌Serial Old收集器是JVM中用于老年代的垃圾收集器‌。
它是Serial收集器的老年代版本,同样采用单线程工作方式,
并且在垃圾收集时需要暂停所有其他工作线程(用户线程),直到垃圾收集完成,
这个过程被称为“Stop The World”(STW)‌

工作原理和特点
Serial Old收集器使用标记-压缩算法进行垃圾收集。它的主要用途包括:

‌与Parallel Scavenge收集器搭配使用‌:在JDK 1.5及以前的版本中,
Serial Old与Parallel Scavenge搭配使用,主要用于服务器端应用。
‌作为CMS收集器的后备方案‌:在CMS收集器无法及时完成垃圾收集时,
Serial Old作为后备方案进行老年代的垃圾收集‌

优缺点
‌优点‌:
‌简单高效‌:由于是单线程工作,实现简单,资源占用少。
‌适用于内存资源有限的环境‌:在客户端模式下,对于几十兆甚至一两百兆的新生代对象,
停顿时间可以控制在可接受范围内‌

‌缺点‌:
‌停顿时间长‌:由于需要暂停所有工作线程,导致应用在垃圾收集期间完全停顿,
影响用户体验和应用程序的响应时间‌
  1. 2.Parallel Old收集器
    • 类型:多线程收集器,老年代。
    • 特点:Parallel Old是Parallel Scavenge收集器的老年代版本,使用多线程和“标记-整理”算法。
    • 适用场景:旨在提高系统吞吐量,适用于多线程环境。
‌Parallel Old收集器‌是JVM(Java虚拟机)中的一个垃圾收集器,主要用于老年代的垃圾收集。
它采用标记-压缩算法,并且是基于并行回收的机制。
Parallel Old收集器的主要特点是其高效的并行处理能力和对吞吐量的优化‌

特点
‌并行回收‌:Parallel Old收集器使用多个线程进行垃圾收集,提高了垃圾收集的效率。
‌标记-压缩算法‌:它使用标记-压缩算法来减少内存碎片,提高内存利用率。
‌Stop-the-World机制‌:在进行垃圾收集时,Parallel Old收集器会暂停所有用户线程(Stop-the-World),直到垃圾收集完成。
使用场景
Parallel Old收集器通常用于需要高吞吐量的应用场景。
它通过减少垃圾收集的停顿时间来优化整体的应用性能,适合长时间运行的大规模应用‌
  1. 3.CMS(Concurrent Mark Sweep)收集器 类型
  • 定位:老年代并发收集器,需配合年轻代收集器(如ParNew)使用。

特点
  1. 目标:以降低停顿时间为核心目标,适合对延迟敏感的应用。

  2. 算法:采用**标记-清除(Mark-Sweep)**算法,非压缩式回收。

  3. 阶段划分

    • 初始标记(Initial Mark):标记GC Roots直接关联的老年代对象(需STW,时间短)。

    • 并发标记(Concurrent Mark):遍历老年代对象图(与用户线程并发)。

    • 重新标记(Remark):修正并发标记期间的变化(需STW,时间较长)。

    • 并发清除(Concurrent Sweep):清理垃圾对象(与用户线程并发)。

优点
  • 低停顿:通过并发标记和清除大幅减少STW时间。

  • 适合交互式应用:如Web服务器、实时交易系统等需快速响应的场景。

缺点
  1. CPU资源敏感

    • 并发阶段占用线程(默认启动(CPU_Cores + 3)/4个线程),在CPU核心数少(如≤4)时,可能导致应用吞吐量显著下降。

  2. 浮动垃圾(Floating Garbage)

    • 并发清理阶段用户线程可能产生新垃圾,若空间不足会触发Concurrent Mode Failure,退化为Serial Old收集器进行Full GC(长时间STW)。

  3. 内存碎片

    • 标记-清除算法不整理内存,长期运行后碎片化严重,可能导致:

      • 晋升失败(Promotion Failed):年轻代对象无法晋升到老年代。

      • 即使老年代总空间足够,因碎片无法分配大对象而触发Full GC。

  4. 内存预留要求

    • CMS需预留足够空间(通过-XX:CMSInitiatingOccupancyFraction设置触发阈值,默认92%),否则易触发并发失败。

  5. JDK版本兼容性

    • JDK 9+标记为废弃,JDK 14中正式移除,建议使用G1或ZGC替代。

适用场景
  • 低延迟需求:要求GC停顿时间控制在几百毫秒以内。

  • 中等堆内存(如4GB~8GB),且应用能容忍周期性Full GC。

  • CPU资源充足(建议≥4核),避免并发阶段争抢资源。

调优关键参数
参数默认值说明
-XX:+UseConcMarkSweepGC-启用CMS收集器
-XX:CMSInitiatingOccupancyFraction92%老年代使用率阈值触发CMS回收
-XX:+UseCMSCompactAtFullCollectiontrueFull GC时进行内存压缩(解决碎片问题,但增加停顿时间)
-XX:CMSFullGCsBeforeCompaction0执行多少次Full GC后触发压缩(0表示每次Full GC都压缩)
-XX:ParallelGCThreads-设置并发阶段的GC线程数(通常设为CPU核心数的25%~30%)
补充说明
  • 与Full GC的关系:CMS的失败(如Concurrent Mode Failure)会触发Serial Old收集器进行Full GC,导致长时间停顿。

  • 碎片问题缓解:可通过-XX:+UseCMSCompactAtFullCollection-XX:CMSFullGCsBeforeCompaction参数控制压缩频率,但会增加停顿时间。

  • 监控指标:需关注Concurrent Mode Failure次数、Full GC频率及耗时、老年代碎片率等。


总结

用户对CMS的描述基本正确,但需注意其已逐步被现代收集器(如G1、ZGC)取代,且存在内存碎片、并发失败等固有缺陷。在JDK 8及之前版本中,CMS仍适用于对延迟敏感的中等规模应用,但在新项目中建议优先考虑G1或低延迟的ZGC/Shenandoah。

‌CMS收集器(Concurrent Mark Sweep)是Java虚拟机(JVM)中的一种垃圾收集器,
主要用于老年代(Old Generation)的垃圾回收‌。
CMS收集器的目标是减少垃圾收集时的应用程序停顿时间(STW,Stop-The-World),
特别适用于对服务响应速度要求较高的场景,如互联网站或B/S系统的服务端Java应用‌

工作原理
CMS收集器使用“标记-清除”算法,其工作过程主要包括以下几个阶段:

‌初始标记‌:暂停所有其他线程,记录下GC Roots直接引用的对象。
‌并发标记‌:从GC Roots开始遍历整个对象图,这个过程可以与用户线程并发进行。
‌重新标记‌:修正并发标记期间因用户程序运行而导致的标记变化。
‌并发清理‌:开启用户线程,GC线程清理未标记的对象。
‌并发重置‌:重置本次GC过程中的标记数据‌

特点
‌并发性‌:CMS设计为并发低停顿的垃圾收集器,使得在垃圾回收过程中用户线程不会停顿或停顿时间很短,
有助于保障系统的响应速度‌

‌标记-清除算法‌:CMS使用标记-清除算法进行垃圾回收,
这种算法在处理过程中需要多次暂停用户线程以确保准确性‌

‌适用场景‌:由于CMS收集器能有效减少停顿时间,特别适合那些对用户体验要求较高的应用场景,
如服务器端应用和需要高并发处理的系统‌

三、兼顾新生代和老年代的垃圾收集器 G1收集器

  1. G1(Garbage-First)收集器

    • 类型:并行与并发收集器,适用于新生代和老年代。
    • 特点
      • 并行与并发‌:G1收集器能够充分利用多核处理器的优势,通过并行执行垃圾收集任务来提高效率。同时,它的大部分工作都是与应用线程并发执行的,从而减少了停顿时间‌。
      • 分区域收集‌:G1将整个堆内存划分为多个大小相等的独立区域(Region),这些区域在逻辑上是连续的,但在物理内存上可能不是连续的。每个Region都可以扮演Eden区、Survivor区或Old区等角色。这种设计使得G1 GC能够更加灵活地进行内存管理和垃圾收集‌。
      • 优先回收垃圾最多区域‌:G1通过跟踪每个Region中的垃圾堆积情况,并根据回收价值和成本进行排序,优先回收垃圾最多的Region。这种策略有助于最大限度地提高垃圾收集的效率‌。
      • 可预测的停顿时间‌:G1通过建立一个可预测的停顿时间模型,允许用户明确指定在一个特定时间片段内,垃圾收集所造成的停顿时间不得超过某个阈值。这使得G1非常适合需要严格控制停顿时间的应用场景‌。
    • 适用场景:面向服务端应用,能充分利用多CPU、多核环境,适用于需要低延迟和可预测停顿时间的大型应用程序。
    • 适合大堆内存

      • G1通过 Region分区机制(默认2048个分区)有效管理大内存堆(4GB~数十GB),规避传统分代GC的全堆扫描问题。

      • 实际应用案例:在16GB以上堆内存场景中,G1的 平均停顿时间 通常比CMS低30%~50%。

    • 简化调优

      • 核心参数确实聚焦于:

        • -Xms/-Xmx(堆初始/最大值)

        • -XX:MaxGCPauseMillis(目标最大停顿时间,默认200ms)

      • 例如,仅设置以下参数即可获得较好表现:

        -XX:+UseG1GC -Xms8g -Xmx8g -XX:MaxGCPauseMillis=150
    • Garbage First设计原则

      • G1通过 回收效益优先模型(Predictive Model),优先回收垃圾比例高(Garbage-First)的Region,确保内存利用率合理。

      • 统计表明,G1的 空间释放效率 比CMS高15%~25%,尤其适合对象生命周期差异大的场景。

    • 进阶调优场景

      • Region大小调整-XX:G1HeapRegionSize):影响大对象分配和回收粒度。

      • 并发线程数-XX:ConcGCThreads):控制并发标记阶段的吞吐量。

      • 混合回收策略-XX:G1MixedGCCountTarget):调整Old Region回收比例。

      • 示例调优参数

        -XX:G1HeapRegionSize=16m \
        -XX:ConcGCThreads=4 \
        -XX:G1MixedGCLiveThresholdPercent=85
    • G1收集器的历史背景和替代CMS收集器

      G1收集器在JDK 7u4版本中被正式推出,并在JDK 9中成为默认的垃圾收集器。它取代了CMS收集器,后者在JDK 9中被废弃,并在JDK 14中被完全移除。G1的设计目的是为了适应不断扩大的内存和增加的处理器数量,进一步降低暂停时间,同时兼顾良好的吞吐量‌

    • 总结:G1是一款面向大堆内存的垃圾收集器,通过Region分区和Garbage-First策略实现低停顿目标。其调优参数简单直观(堆大小和最大暂停时间),但需注意元数据内存开销。在JDK 11+中,G1通过算法优化显著提升了吞吐量和稳定性,成为多数场景的默认选择

性能数据参考

指标G1(JDK 17)CMS(JDK 8)ZGC(JDK 17)
最大堆内存支持16TB16GB16TB
平均停顿时间(ms)50~200100~3001~10
吞吐量损失5%~10%10%~20%<5%
内存开销中等

参考:详解 JVM Garbage First(G1) 垃圾收集器-腾讯云开发者社区-腾讯云

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

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

相关文章

Sourcetree——使用.gitignore忽略文件或者文件夹

一、为何需要文件忽略机制&#xff1f; 1.1 为什么要会略&#xff1f; 对于开发者而言&#xff0c;明智地选择忽略某些文件类型&#xff0c;能带来三大核心优势&#xff1a; 仓库纯净性&#xff1a;避免二进制文件、编译产物等污染代码库 安全防护&#xff1a;防止敏感信息&…

本地部署 OpenManus 保姆级教程(Windows 版)

一、环境搭建 我的电脑是Windows 10版本&#xff0c;其他的没尝试&#xff0c;如果大家系统和我的不一致&#xff0c;请自行判断&#xff0c;基本上没什么大的出入啊。 openManus的Git地址&#xff1a;https://github.com/mannaandpoem/OpenManus 根据官网的两种安装推荐方式如…

视频推拉流:EasyDSS平台直播通道重连转推失败原因排查与解决

视频推拉流EasyDSS视频直播点播平台&#xff0c;集视频直播、点播、转码、管理、录像、检索、时移回看等功能于一体&#xff0c;可提供音视频采集、视频推拉流、播放H.265编码视频、存储、分发等视频能力服务。 用户使用EasyDSS平台对直播通道进行转推&#xff0c;发现只要关闭…

【科研绘图系列】python绘制分组点图(grouped dot plot)

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包数据下载导入数据函数`generateRectBoxDF` 函数主要作用参数解释逻辑流程`nmfDotPlot` 函数主要作用参数解释逻辑流程画图1画图2画图3画图4介绍 【科研绘图系列】python绘制…

Springfox、Springdoc和Swagger

Springfox、Swagger 和 Springdoc Springfox、Swagger 和 Springdoc 是用于在 Spring Boot 项目中生成API文档的工具&#xff0c;但它们之间有显著的区别和演进关系&#xff1a; 1.Swagger 简介 Swagger 是一个开源项目&#xff0c;旨在为 RESTful APIs 提供交互式文档。最…

在Spring Boot项目中如何实现获取FTP远端目录结构

Java语言实现获取FTP远端目录结构的实现方式有多种,在Spring Boot 项目中,最简单和快速的方式就是使用Spring Integration 实现FTP相关的功能。 前言 本篇的示例和演示基于Windows 的FTP 服务,关于如何在Windows 开启FTP服务可以参考: Windows 如何开启和使用FTP服务 本…

Flutter_学习记录_device_info_plus 插件获取设备信息

引入三方库device_info_plus导入头文件 import package:device_info_plus/device_info_plus.dart;获取设备信息的主要代码 DeviceInfoPlugin deviceInfoPlugin DeviceInfoPlugin(); BaseDeviceInfo deviceInfo await deviceInfoPlugin.deviceInfo;完整案例 import package…

Java高频面试之集合-10

hello啊&#xff0c;各位观众姥爷们&#xff01;&#xff01;&#xff01;本baby今天来报道了&#xff01;哈哈哈哈哈嗝&#x1f436; 面试官&#xff1a;详解红黑树&#xff1f;HashMap为什么不用二叉树/平衡树呢&#xff1f; 一、红黑树&#xff08;Red-Black Tree&#xff…

never_give_up

一个很有意思的题&#xff1a; never_give_up - Bugku CTF平台 注意到注释里面有1p.html&#xff0c;我们直接在源代码界面看&#xff0c;这样就不会跳转到它那个链接的&#xff1a; 然后解码可得&#xff1a; ";if(!$_GET[id]) {header(Location: hello.php?id1);exi…

Python Selenium库入门使用,图文详细。附网页爬虫、web自动化操作等实战操作。

文章目录 前言1 创建conda环境安装Selenium库2 浏览器驱动下载&#xff08;以Chrome和Edge为例&#xff09;3 基础使用&#xff08;以Chrome为例演示&#xff09;3.1 与浏览器相关的操作3.1.1 打开/关闭浏览器3.1.2 访问指定域名的网页3.1.3 控制浏览器的窗口大小3.1.4 前进/后…

AI4CODE】3 Trae 锤一个贪吃蛇的小游戏

【AI4CODE】目录 【AI4CODE】1 Trae CN 锥安装配置与迁移 【AI4CODE】2 Trae 锤一个 To-Do-List 这次还是采用 HTML/CSS/JAVASCRIPT 技术栈 Trae 锤一个贪吃蛇的小游戏。 1 环境准备 创建一个 Snake 的子文件夹&#xff0c;清除以前的会话记录。 2 开始构建 2.1 输入会…

Linux 进程的一生(一):进程与线程的创建机制解析

在 Linux 操作系统中&#xff0c;每个任务都以「进程」的形式存在。但 Linux 下的「线程」又是什么&#xff1f;Linux 并没有单独定义一种全新数据结构来表示线程&#xff0c;而是将线程视为一种特殊的进程——一种共享资源的轻量级进程。然而&#xff0c;在具体实现和运行机制…

STM32之I2C硬件外设

注意&#xff1a;硬件I2C的引脚是固定的 SDA和SCL都是复用到外部引脚。 SDA发送时数据寄存器的数据在数据移位寄存器空闲的状态下进入数据移位寄存器&#xff0c;此时会置状态寄存器的TXE为1&#xff0c;表示发送寄存器为空&#xff0c;然后往数据控制寄存器中一位一位的移送数…

windows版本的时序数据库TDengine安装以及可视化工具

了解时序数据库TDengine&#xff0c;可以点击官方文档进行详细查阅 安装步骤 首先找到自己需要下载的版本&#xff0c;这边我暂时只写windows版本的安装 首先我们需要点开官网&#xff0c;找到发布历史&#xff0c;目前TDengine的windows版本只更新到3.0.7.1&#xff0c;我们…

【AI】单台10卡4090 openEuler服务器离线部署kasm workspace 提供简单的GPU云服务 虚拟化桌面

下载网址 Downloads | Kasm Workspaces 文件连接 wget https://kasm-static-content.s3.amazonaws.com/kasm_release_plugin_images_amd64_1.16.1.98d6fa.tar.gz wget https://kasm-static-content.s3.amazonaws.com/kasm_release_1.16.1.98d6fa.tar.gz wget https://kasm-st…

NetAssist 5.0.14网络助手基础使用及自动应答使用方案

以下是NetAssist v5.0.14自动应答功能的详细使用步骤&#xff1a; 一、基础准备&#xff1a; 工具下载网址页面&#xff1a;https://www.cmsoft.cn/resource/102.html 下载安装好后&#xff0c;根据需要可以创建多个server&#xff0c;双击程序图标运行即可&#xff0c;下面…

47.HarmonyOS NEXT 登录模块开发教程(二):一键登录页面实现

温馨提示&#xff1a;本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦&#xff01; HarmonyOS NEXT 登录模块开发教程&#xff08;二&#xff09;&#xff1a;一键登录页面实现 文章目录 HarmonyOS NEXT 登录模块开发教程&#xff0…

5.1 程序调试

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的 本节中为了演示方便&#xff0c;使用的代码如下&#xff1a; 【例 5.1】【项目&#xff1a;code5-001】程序的调试。 static void Ma…

Cursor初体验:excel转成CANoe的vsysvar文件

今天公司大佬先锋们给培训了cursor的使用&#xff0c;还给注册了官方账号&#xff01;跃跃欲试&#xff0c;但是测试任务好重&#xff0c;结合第三方工具开发也是没有头绪。 但巧的是&#xff0c;刚好下午有同事有个需求&#xff0c;想要把一个几千行的excel转成canoe的系统变…

vue3-element-admin 前后端本地启动联调

一、后端环境准备 1.1、下载地址 gitee 下载地址 1.2、环境要求 JDK 17 1.3、项目启动 克隆项目 git clone https://gitee.com/youlaiorg/youlai-boot.git数据库初始化 执行 youlai_boot.sql 脚本完成数据库创建、表结构和基础数据的初始化。 修改配置 application-dev.y…