当前位置: 首页 > news >正文

JVM | CMS垃圾收集器详解

目录

CMS垃圾回收器简介

为什么CMS图中初始标记的阶段是单线程?为啥不多线程?当然现在默认多线程了。

CMS的两种模式与一种特殊策略

Backgroud CMS

记忆集

卡表

ForeGroud CMS

CMS的标记压缩算法

三色标记 (便于理解而被后人提出)

CMS标记清除的全局整理

CMS常见参数

CMS的线程数计算公式

ParallelGCThreads

ConcGCThreads


首先,在看垃圾回收器的内容之前,需要对基础的三种垃圾回收算法有所了解: JVM垃圾回收

CMS垃圾回收器简介

CMS(Concurrent Mark Sweep)收集器是一种以 获取 最短停顿时间 为目标的收集器。

采用的是标记-清除算法,整体分四个步骤(注:CMS中并不是只有标记-清除算法哦)

  1. 初始标记(CMS initial mark) 标记清除GC Root直接关联对象,不用Tracing,速度很快

  2. 并发标记(CMS concurrent mark) 进行GC Roots Tracing

  3. 重新标记(CMS reamrk)修改并发标记 因用户程序变动的内容

  4. 并发清除(CMS concurrent sweep) 清除不可达对象空间,同时有新垃圾产生,留着下次清理(浮动垃圾)

由于整个过程中,并发标记和并发清除,收集器线程可以与用户线程一起工作,所以总体来说CMS的内存回收过程是与用户线程一起并发执行的。(是优点也是缺点)

  • 优点:并发收集、低停顿

  • 缺点:产生大量空间碎片、并发阶段会降低吞吐量

为什么CMS图中初始标记的阶段是单线程?为啥不多线程?当然现在默认多线程了。

初始化标记阶段是串行的,JDK7的行为。JDK8中默认是并行的。

调整参数:-XX:+CMSParallelInitialMarkEnabled

因为当时的技术,关于并发操作少人使用。JDK8中用多线程的人多了起来,那人技术本身不行的情况下,初始标记也设计成串行的合理吧。那后面重新标记为啥是并发的?哥们,咱并发标记的用户线程空着也是空着,拿走做重新标记呗~

CMS的两种模式与一种特殊策略

Backgroud CMS

其实并发标记的过程还可以整理为两个流程:并发标记-并发预处理、可中止的预处理。

为什么呢?

思考一下,CMS要进行老年代垃圾回收的时候,如何判定 老年代对象 被 年轻代对象 引用了?

答案:必须扫描新生代来确认,对不。所以这是CMS虽然是老年代垃圾回收器,却需要扫描新生代的原因。

既然这个时候要扫描新生代,全盘扫描的时候会不会很慢?

会。那么,怎么实现 以 停顿时间最短 为目标呢?那么我们需要考虑如何让他变快,全盘扫描要快速,可以让垃圾少点呀。垃圾越少,扫描越快。

那么,CMS两个参数,就自然而然了。

CMSScheduleRemarkEdenSizeThreshold 默认值:2M

CMSScheduleRemarkEdenPenetration 默认值:50%

这两个参数组合起来就是预清理之后,Eden空间使用超过2M的时候启动可中断的并发预清理(CMS-concurrent-abortable-preclean),到Eden空间使用率到达50%的时候中断(但不是结束),进入Remark(重新标记阶段)。

那么,为啥是可中断呢?

程序什么时候进行minorGC ,我们不知道,这是游由JVM来调度的。总不能一直在执行并发标记吧,总要有个结束的时刻。

故 CMS提供了一个参数CMSMaxAbortablePrecleanTime ,默认为5S

只要到了5S,不管发没发生Minor GC,有没有到CMSScheduleRemardEdenPenetration都会中止此阶段,进入remark。

如果在5S内还是没有执行Minor GC怎么办?

CMS提供CMSScavengeBeforeRemark参数,使remark前强制进行一次Minor GC。

到这里,新生代策略已经聊完了

接下来看下老年代中几个关键的点

记忆集

当我们进行young gc时,我们的gc roots除了常见的栈引用、静态变量、常量、锁对象、class对象这些常见的之外,如果 老年代有对象引用了新生代对象 ,那么老年代的对象也应该加入gc roots的范围中,但是如果每次进行young gc我们都需要扫描一次老年代的话,那进行垃圾回收的代价实在是太大了,因此引入了一种叫做记忆集的抽象数据结构来记录这种引用关系。

记忆集是一种用于记录从非收集区域指向收集区域的指针集合的数据结构。

出于效率与成本的问题,引入了卡表的数据结构

卡表

如果说记忆集是我们针对于跨代引用问题提出的思想,卡表则是针对于该种思想的具体实现。(可以理解为记忆集是结构,卡表是实现类)

在hotspot虚拟机中,卡表是一个字节数组,数组的每一项对应着内存中的某一块连续地址的区域,如果该区域中有引用指向了待回收区域的对象,卡表数组对应的元素将被置为1,没有则置为0;

  • 卡表是使用一个字节数组实现:CARD_TABLE[],每个元素对应着其标识的内存区域一块特定大小的内存块,称为"卡页"。hotSpot使用的卡页是2^9大小,即512字节

  • 一个卡页中可包含多个对象,只要有一个对象的字段存在跨代指针,其对应的卡表的元素标识就变成1,表示该元素变脏,否则为0。GC时,只要筛选本收集区的卡表中变脏的元素加入GC Roots里。

卡表其他作用:

老年代识别新生代的时候

对应的card table被标识为相应的值(card table中是一个byte,有八位,约定好每一位的含义就可区分哪个是引用新生代,哪个是并发标记阶段修改过的)

ForeGroud CMS

这个也是CMS一种收集模式,但是他是并发失败才会走的模式。

如果 并发搜集器不能在年老代填满之前完成不可达(unreachable)对象的回收 ,或者 年老代中有效的空闲内存空间不能满足某一个内存的分配请求 ,此时应用会被暂停,并在此暂停期间开始垃圾回收,直到回收完成才会恢复应用程序。这种无法并发完成搜集的情况就成为 并发模式失败(concurrent mode failure) ,而且这种情况的发生也意味着我们需要调节并发搜集器的参数了。

-XX:CMSInitiatingOccupancyFraction

-XX:+UseCMSInitiatingOccupancyOnly

注意:-XX:+UseCMSInitiatingOccupancyOnly 只是用设定的回收阈值(上面指定的70%),如果不指定,JVM仅在第一次使用设定值,后续则自动调整.这两个参数表示只有在Old区占了CMSInitiatingOccupancyFraction设置的百分比的内存时才满足触发CMS的条件。注意这只是满足触发CMS GC的条件。至于什么时候真正触发CMS GC,由一个后台扫描线程决定。CMSThread默认2秒钟扫描一次,判断是否需要触发CMS,这个参数可以更改这个扫描时间间隔。

当老年代达到 ((100 - 40) + (double) 80 * 40 / 100 ) / 100 = 92 %时,会触发CMS回收。

((100 - MinHeapFreeRatio) + (double)( CMSTriggerRatio * MinHeapFreeRatio) / 100.0) / 100.0

CMS的标记压缩算法

他的回收方式其实就是滑动整理,并且进行整理的时候一般都是两个参数

-XX:+UseCMSCompactAtFullCollection

-XX:CMSFullGCsBeforeCompaction=0

这两个参数表示多少次FullGC后采用MSC算法压缩堆内存,0表示每次FullGC后都会压缩,同时0也是默认值

碎片问题也是CMS采用的标记清理算法最让人诟病的地方:Backgroud CMS采用的标记清理算法会导致内存碎片问题,从而埋下发生FullGC导致长时间STW的隐患。

所以如果触发了FullGC,无论是否会采用MSC算法压缩堆,那都是ParNew+CMS组合非常糟糕的情况。因为这个时候并发模式已经搞不定了,而且整个过程单线程,完全STW,可能会压缩堆(是否压缩堆通过上面两个参数控制),真的不能再糟糕了!想象如果这时候业务量比较大,由于FullGC导致服务完全暂停几秒钟,甚至上10秒,对用户体验影响很大。

三色标记 (便于理解而被后人提出)

  • 黑色:表示对象已经被垃圾收集器访问过, 且这个对象的所有引用都已经扫描过。 黑色的对象代表已经扫描过, 它是安全存活的, 如果有其他对象引用指向了黑色对象, 无须重新扫描一遍。 黑色对象不可能直接(不经过灰色对象) 指向某个白色对象。

  • 灰色:表示对象已经被垃圾收集器访问过, 但这个对象上至少存在一个引用还没有被扫描过。

  • 白色:表示对象尚未被垃圾收集器访问过。 显然在可达性分析刚刚开始的阶段, 所有的对象都是白色的, 若在分析结束的阶段, 仍然是白色的对象, 即代表不可达。

标记过程:

  1. 初始时,所有对象都在 【白色集合】中;

  2. 将GC Roots 直接引用到的对象 挪到 【灰色集合】中;

  3. 从灰色集合中获取对象:

    1. 将本对象 引用到的 其他对象 全部挪到 【灰色集合】中;

    2. 将本对象 挪到 【黑色集合】里面。

重复步骤3.a,直至【灰色集合】为空时结束。

结束后,仍在【白色集合】的对象即为GC Roots 不可达,可以进行回收

问题1:多标-浮动垃圾

在并发标记过程中,如果由于方法运行结束导致部分局部变量(gcroot)被销毁,这个gcroot引用的对象之前又被扫描过 (被标记为非垃圾对象),那么本轮GC不会回收这部分内存。这部分本应该回收但是没有回收到的内存,被称之为“浮动 垃圾”。浮动垃圾并不会影响垃圾回收的正确性,只是需要等到下一轮垃圾回收中才被清除。

另外,针对并发标记(还有并发清理)开始后产生的新对象,通常的做法是直接全部当成黑色,本轮不会进行清除。这部分 对象期间可能也会变为垃圾,这也算是浮动垃圾的一部分。

问题2:漏标-读写屏障(漏标会导致被引用的对象被当成垃圾误删除,这是严重bug,必须解决)

漏标只有同时满足以下两个条件时才会发生:

  • 条件一:灰色对象 断开了 白色对象的引用;即灰色对象 原来成员变量的引用 发生了变化。

  • 条件二:黑色对象 重新引用了 该白色对象;即黑色对象 成员变量增加了 新的引用。

有两种解决方案: 增量更新(Incremental Update) 和原始快照(Snapshot At The Beginning,SATB)

  • 增量更新就是当黑色对象插入新的指向白色对象的引用关系时, 就将这个新插入的引用记录下来, 等并发扫描结束之后, 再将这些记录过的引用关系中的黑色对象为根, 重新扫描一次。 这可以简化理解为, 黑色对象一旦新插入了指向白色对象的引用之后, 它就变回灰色对象了。

  • 原始快照就是当灰色对象要删除指向白色对象的引用关系时, 就将这个要删除的引用记录下来, 在并发扫描结束之后, 再将这些记录过的引用关系中的灰色对象为根, 重新扫描一次,这样就能扫描到白色的对象,将白色对象直接标记为黑色(目的就是让这种对象在本轮gc清理中能存活下来,待下一轮gc的时候重新扫描,这个对象也有可能是浮动垃圾)

以上无论是对引用关系记录的插入还是删除, 虚拟机的记录操作都是通过写屏障实现的。

写屏障实现原始快照(SATB): 当对象B的成员变量的引用发生变化时,比如引用消失(a.b.d = null),我们可以利用写屏障,将B原来成员变量的引用对象D记录下来:

写屏障实现增量更新: 当对象A的成员变量的引用发生变化时,比如新增引用(a.d = d),我们可以利用写屏障,将A新的成员变量引用对象D 记录下来。

CMS标记清除的全局整理

由于CMS使用的是标记清除算法,而标记清除算法会有大量的内存碎片的产生,所以JVM提供了

-XX:+UseCMSCompactAtFullCollection参数用于在全局GC(full GC)后进行一次碎片整理的工作,

由于每次全局GC后都进行碎片整理会较大的影响停顿时间,JVM又提供了参数

-XX:CMSFullGCsBeforeCompaction 控制在几次全局GC后会进行碎片整理

CMS常见参数

-XX:+UseConcMarkSweepGC

打开CMS GC收集器。JVM在1.8之前默认使用的是Parallel GC,9以后使用G1 GC。

-XX:+UseParNewGC

当使用CMS收集器时,默认年轻代使用多线程并行执行垃圾回收(UseConcMarkSweepGC开启后则默认开启)。

-XX:+CMSParallelRemarkEnabled

采用并行标记方式降低停顿(默认开启)。

-XX:+CMSConcurrentMTEnabled

被启用时,并发的CMS阶段将以多线程执行(因此,多个GC线程会与所有的应用程序线程并行工作)。(默认开启)

-XX:ConcGCThreads

定义并发CMS过程运行时的线程数。

-XX:ParallelGCThreads

定义CMS过程并行收集的线程数。

-XX:CMSInitiatingOccupancyFraction

该值代表老年代堆空间的使用率,默认值为68。当老年代使用率达到此值之后,并行收集器便开始进行垃圾收集,该参数需要配合UseCMSInitiatingOccupancyOnly一起使用,单独设置无效。

-XX:+UseCMSInitiatingOccupancyOnly

该参数启用后,参数CMSInitiatingOccupancyFraction才会生效。默认关闭。

-XX:+CMSClassUnloadingEnabled

相对于并行收集器,CMS收集器默认不会对永久代进行垃圾回收。如果希望对永久代进行垃圾回收,可用设置-XX:+CMSClassUnloadingEnabled。默认关闭。

-XX:+CMSIncrementalMode

开启CMS收集器的增量模式。增量模式使得回收过程更长,但是暂停时间往往更短。默认关闭。

-XX:CMSFullGCsBeforeCompaction

设置在执行多少次Full GC后对内存空间进行压缩整理,默认值0。

-XX:+CMSScavengeBeforeRemark

在cms gc remark之前做一次ygc,减少gc roots扫描的对象数,从而提高remark的效率,默认关闭。

-XX:+ExplicitGCInvokesConcurrent

该参数启用后JVM无论什么时候调用系统GC,都执行CMS GC,而不是Full GC。

-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses

该参数保证当有系统GC调用时,永久代也被包括进CMS垃圾回收的范围内。

-XX:+DisableExplicitGC

该参数将使JVM完全忽略系统的GC调用(不管使用的收集器是什么类型)。

-XX:+UseCompressedOops

这个参数用于对类对象数据进行压缩处理,提高内存利用率。(默认开启)

-XX:MaxGCPauseMillis=200

这个参数用于设置GC暂停等待时间,单位为毫秒,不要设置过低。

CMS的线程数计算公式

区分young区的parnew gc线程数和old区的cms线程数,分别为以下两参数:

  • -XX:ParallelGCThreads=m // STW暂停时使用的GC线程数,一般用满CPU

  • -XX:ConcGCThreads=n // GC线程和业务线程并发执行时使用的GC线程数,一般较小

ParallelGCThreads

其中ParallelGCThreads 参数的默认值是:

  • CPU核心数 <= 8,则为 ParallelGCThreads=CPU核心数,比如4C8G取4,8C16G取8

  • CPU核心数 > 8,则为 ParallelGCThreads = CPU核心数 * 5/8 + 3 向下取整

  • 16核的情况下,ParallelGCThreads = 13

  • 32核的情况下,ParallelGCThreads = 23

  • 64核的情况下,ParallelGCThreads = 43

  • 72核的情况下,ParallelGCThreads = 48

ConcGCThreads

ConcGCThreads的默认值则为:

ConcGCThreads = (ParallelGCThreads + 3)/4 向下取整。

  • ParallelGCThreads = 1~4时,ConcGCThreads = 1

  • ParallelGCThreads = 5~8时,ConcGCThreads = 2

  • ParallelGCThreads = 13~16时,ConcGCThreads = 4

相关文章:

JVM | CMS垃圾收集器详解

目录 CMS垃圾回收器简介 为什么CMS图中初始标记的阶段是单线程&#xff1f;为啥不多线程&#xff1f;当然现在默认多线程了。 CMS的两种模式与一种特殊策略 Backgroud CMS 记忆集 卡表 ForeGroud CMS CMS的标记压缩算法 三色标记 &#xff08;便于理解而被后人提出&am…...

android开发中的多线程、数据存储同步功能实现方案和应用场景

在Android开发中&#xff0c;多线程、数据存储与同步功能有多种实现方案&#xff0c;以下是详细介绍及其应用场景&#xff1a; 多线程 实现方案&#xff1a; Thread类与Runnable接口&#xff1a;通过继承Thread类并重写run方法&#xff0c;或实现Runnable接口并将其传入Threa…...

【C++初阶】--- 模板进阶

1.非类型模板参数 • 模板参数分类类型形参与非类型形参。 • 类型形参即&#xff1a;出现在模板参数列表中&#xff0c;跟在class或者typename之类的参数类型名称。 • 非类型形参&#xff0c;就是用一个常量作为类(函数)模板的一个参数&#xff0c;在类(函数)模板中可将该参…...

数据库所有知识

# 第一章 数据库-理论基础 ## 1.1 什么是数据库 数据&#xff1a; 描述事物的符号记录&#xff0c; 可以是数字、 文字、图形、图像、声音、语言等&#xff0c;数据有多种形式&#xff0c;它们都可以经过数字化后存入计算机。 数据库&#xff1a; 存储数据的仓库&#xff0c…...

docker部署的Nextcloud,处于维护模式,如何解决

Nextcloud 在升级后卡在维护模式&#xff0c;以下是针对 Docker 部署的解决方案&#xff1a; 1. 通过 OCC 命令强制关闭维护模式 进入 Nextcloud 容器内部执行命令&#xff1a; # 替换 nextcloud 为你的容器名称 docker exec -it --user www-data nextcloud php occ maintena…...

mongoose插入文档,字段类型, 字段验证, 删除文档,更新文档,读取文档,查询文档的条件控制 ,字段筛选,数据排序,数据截取

、Mongoose 中与 文档操作&#xff08;插入、查询、更新、删除&#xff09;及其相关功能&#xff08;字段类型、验证、条件筛选、排序、分页等&#xff09;相关示例&#xff1a; &#x1f4cb; 一、字段类型定义&#xff08;Schema Types&#xff09; const mongoose require…...

源码编译安装LAMP

一&#xff1a;LAMP概述 LAMP架构是目前成熟的企业网站应用模式之一&#xff0c;指的是协同工作的一整套系统和相关软件&#xff0c;能够提供动态Web站点服务及其应用开发环境。LAMP是一个缩写词&#xff0c;具体包括Linux操作系统、Apache网站服务器、MySQL数据库服务器、PHP…...

C++每日训练 Day 18:构建响应式表单与数据验证(初学者友好)

&#x1f4d8; 本篇目标&#xff1a;在前几日协程与事件驱动机制基础上&#xff0c;构建一个响应式表单系统&#xff0c;实现用户输入的异步验证与反馈。通过协程挂起/恢复机制&#xff0c;简化异步逻辑&#xff0c;提升代码可读性。 &#x1f501; 回顾 Day 17&#xff1a;响应…...

Linux环境变量以及进程虚拟地址原理

目录 一、介绍进程优先级 1.什么是优先级 2.为什么会有优先级 3.Linux中的优先级是怎么确定的 1&#xff09;查看Linux中的优先级 2&#xff09;计算优先级和更改优先级 二、环境变量 1.什么是环境变量 2.环境变量有什么作用 3.环境变量怎么做到的 1&#xff09;查看系统已有的…...

基于非递归求解的汉诺塔超级计算机堆栈与数据区设计方案

基于非递归求解的汉诺塔超级计算机堆栈与数据区设计方案 一、设计背景与目标 汉诺塔问题存在非递归直接求解方法&#xff0c;相较于递归法具有明确移动规律和潜在性能优势。本设计旨在利用非递归求解规律&#xff0c;优化汉诺塔超级计算机的堆栈与数据区结构&#xff0c;降低…...

【Linux应用】在PC的Linux环境下通过chroot运行ARM虚拟机镜像img文件(需要依赖qemu-aarch64、不需要重新安装iso)

【Linux应用】在PC的Linux环境下通过chroot运行ARM虚拟机镜像img文件&#xff08;需要依赖qemu-aarch64、不需要重新安装iso&#xff09; qemu提供了运行ARM虚拟机的方法 具体的操作方式就是建立一个硬盘img 然后通过iso安装到img 最后再运行img即可 这种方式教程很多 很简单 …...

CISC与RISC详解:定义、区别及典型处理器

一、CISC&#xff08;复杂指令集计算机&#xff09; Complex Instruction Set Computer 核心思想&#xff1a;通过设计复杂的指令&#xff0c;减少程序指令数量&#xff0c;以硬件复杂度换取编程便利性。 主要特点&#xff1a; 指令复杂度高&#xff1a; 单条指令可完成多步操…...

数据库中DDL、DML、DCL的区别是什么?

数据库中DDL、DML、DCL的区别是什么&#xff1f; 在数据库的使用过程中&#xff0c;SQL&#xff08;结构化查询语言&#xff09;常常被用来执行不同的操作&#xff0c;主要分为三类&#xff1a;DDL&#xff08;数据定义语言&#xff09;、DML&#xff08;数据操纵语言&#xf…...

【东枫电子】AI-RAN:人工智能 - 无线接入网络

太原市东枫电子科技有限公司&#xff0c;翻译 文章目录 1.概述1.1 什么是AI-RAN&#xff1f;1.2 为什么是AI-RAN&#xff1f;1.3 AI-RAN有哪些好处&#xff1f;1.4 为什么 AI-RAN 会给通信服务提供商 (CoSP) 带来变革&#xff1f;1.5 AIRAN 的构建模块是什么&#xff1f; 2. 参…...

实习技能记录【5】-----项目中消息传递到ui层的方法

代码 while (1){osEvent evt;evt osMailGet(ui_msg_mailbox, 0);if (evt.status osEventMail){UI_MSG_APP_T *msg (UI_MSG_APP_T *)evt.value.p;if (msg->cmd_type CMD_TYPE_INNER){if (msg->cmd_code CMD_CODE_INNER_REFRESH_NOW){lv_obj_invalidate(lv_scr_act()…...

4.29【Q】paraCompute

还是同样的要求&#xff0c;我要写实验报告&#xff0c;如何组织描述运行时间&#xff0c;加速比&#xff0c;效率等随数据规模&#xff0c;进程数&#xff0c;线程数变化的语言和逻辑&#xff0c;从而显得不冗余和精简&#xff1f;为我生成合理排版&#xff0c;布局的文字&…...

什么是布林带?

什么是布林带&#xff1f; 布林带是约翰布林格在20世纪80年代开发的一种广泛使用的技术分析工具。布林带由价格图表上的三条线组成&#xff1a;中轨、上轨和下轨。中轨通常是20天简单移动平均线&#xff08;SMA&#xff09;&#xff0c;代表资产在此期间的平均价格。上轨和下轨…...

爬虫学习笔记(四)---request入门

例1 例1&#xff1a;写一个爬取百度搜索页面的程序&#xff0c;以搜索一个喜欢的明星为例&#xff08;如在搜索框中输入周杰伦&#xff09; 正常搜索 页面 爬虫思路&#xff1a; 1.用一个query变量&#xff0c;在控制台输入的方式更加灵活的输入想爬取的明星的百度搜索页面 …...

JSON配置文件格式全解析与多语言实战指南

JSON配置文件格式全解析与多语言实战指南 摘要 本文全面解析JSON配置文件的核心语法规范&#xff0c;深入探讨数据类型、转义机制及JSON5扩展特性&#xff0c;提供JavaScript/Python/Java等多语言解析方案。通过典型应用场景案例演示JSON的最佳实践&#xff0c;帮助开发者高效…...

JavaScript 中的类型转换机制?

一、类型转换的两种模式 1. 显式转换&#xff08;手动翻译&#xff09; 你主动告诉 JavaScript 如何转换类型&#xff0c;比如&#xff1a; let num Number("123"); // 字符串 → 数字&#xff1a;123 let str String(123); // 数字 → 字符串&#xff1a;&qu…...

【分享】音频音乐剪辑[特殊字符]人声分离伴奏提取[特殊字符]拼接合并

音频音乐剪辑是一款专业的剪辑软件。在剪辑过程中&#xff0c;它可以对音频进行拼接合成、音乐裁剪、变调变速、格式转换&#xff0c;同时音频音乐剪辑还是一款支持高清录音、音频降噪等众多功能于一体的音频制作软件。 【应用名称】&#xff1a;音频剪辑 【应用版本】&#xf…...

关于 const a 定义的数据 与 其渲染 的问题。即通过const定义的常量,会不会导致渲染不及时。

情况1 &#xff08;同2、4结论一致&#xff09; 定义&#xff1a;使用子hook&#xff0c;将数据 const a 【对stateX的一系列操作】 封存到子hook里。并return出去。结果&#xff1a;此种情况不影响实时渲染。缺点&#xff1a;只要stateX变更&#xff0c;一定展示c的最新数据…...

开源Kotlin从零单排0基础完美入门教程

&#x1f680; Kotlin 从零单排 一个让你欲罢不能的 Kotlin 入门教程&#xff01; 教程仓库地址 &#x1f44b; Hey&#xff0c;你好啊&#xff01; 如果你&#xff1a; &#x1f914; 听说 Kotlin 很香&#xff0c;但不知道香在哪&#xff1f;&#x1f605; Java 写得头大&a…...

主流微前端框架比较

主流微前端框架比较 以下表格列出了当前主流微前端框架的核心对比信息,包括基本介绍、核心特性、适用场景、技术栈兼容性、优缺点、社区维护情况和典型应用案例等: 框架基本介绍核心特性与机制适用场景技术栈兼容性优缺点社区维护情况典型应用案例qiankun蚂蚁金服推出的生产…...

DOM 事件的处理通常分为三个阶段:捕获、目标、冒泡【前端示例】

如果神明还不帮你&#xff0c;说明他相信你。 目录 引言&#xff1a;捕获阶段&#xff1a;目标阶段&#xff1a;冒泡阶段&#xff1a;事件传播示意图&#xff1a;示例&#xff1a;代码&#xff1a;解读&#xff1a;输出&#xff1a; 引言&#xff1a; DOM 事件的处理通常分为三…...

C#实现对达索(Dassault)SolidWorks中3D图纸转化为手机可直接查看预览图纸格式

转化环境无需安装SolidWorks。 代码更新&#xff1a;暂不公开。 实现效果&#xff1a;...

Twitter 工作原理|架构解析|社交APP逻辑

这是对Twitter 工作原理&#xff5c;架构解析&#xff5c;社交APP逻辑_哔哩哔哩_bilibili的学习&#xff0c;感谢up小凡生一 在两年半前&#xff0c;埃隆马斯克收购了Twitter&#xff0c;并且进行了一系列重大改革。今天我们来解析一下这个全球知名社交平台的架构。首先&#x…...

模拟集成电路设计与仿真 : Feedback System

前情提要 此為作者針對迴授系統&#xff0c;進行資料統整&#xff0c;以便日後查詢 原理 1. The Whole System 更正 : V - V feedback 是 並 - 串 迴授 2. Feedback Block Beta 更正 : &#xff0c;所以 the whole systemfeedback block左 2右 1 feedback block feed…...

Linux权限管理进阶:文件归属、特殊权限与ACL详解

一、文件归属管理&#xff1a;chown命令 1. 基础语法与作用 chown 命令用于修改文件或目录的 属主&#xff08;Owner&#xff09; 和 属组&#xff08;Group&#xff09;&#xff0c;是Linux权限管理中调整资源归属的核心工具。 chown [选项] 新属主:新属组 文件/目录 常用…...

MyBatis、MyBatis-Plus、Hibernate、Spring Data JPA 等 Java 持久层技术的理解和对比

一、基本概念 1. MyBatis 是一个 半自动的 ORM 框架&#xff08;Object-Relational Mapping&#xff09;&#xff0c;用于简化 JDBC 开发。它允许你通过 XML 或注解配置 SQL 语句&#xff0c;将 Java 对象与 SQL 查询结果进行映射。 2. MyBatis-Plus&#xff08;MP&#xff…...

如何用vivado导出pin delay

目录 简介&#xff1a; Vivado工具导出pin delay步骤&#xff1a; 简介&#xff1a; 通过在一些等长要求比较严格的场合&#xff0c;会考虑到FPGA内部的走线&#xff0c;这时候就需要用到方法去导出fpga的pin delay。本文以xinlinx 的UltraScale系列的XCKU060-2FFVA1156I为例…...

【图片识别改名】批量读取图片区域文字识别后批量改名,基于Python和腾讯云的实现方案

项目场景 ​​办公文档管理​​&#xff1a;将扫描的发票、合同等文档按编号、日期自动重命名。例如&#xff0c;识别“编号:2023001 日期:20230403”生成“2023001_20230403.jpg”。​​产品图片整理​​&#xff1a;电商产品图片按产品编号、名称自动命名。例如&#xff0c;…...

数字中国浪潮下:Coremail AI赋能邮件办公,筑牢安全防线引领转型

4月28日&#xff0c;在第八届数字中国建设峰会新产品新技术发布会上&#xff0c;Coremail分享了AI在邮件产品领域的最新应用成果和实践经验。 作为互联网之后的又一波技术浪潮&#xff0c;人工智能&#xff08;AI&#xff09;已成为推动各行业变革的核心力量&#xff0c;为企业…...

软件设计师-软考知识复习(1)

写在前面 复习软考&#xff0c;把一些忘记了的知识整理一下&#xff0c;方便后续查看。 设码长为8&#xff0c;补码为11111111&#xff0c;其真值是多少&#xff08; &#xff09; A.1 B.-1 C.127 D.128 参考答案&#xff1a;B 解题步骤 1. 理解补码表示法 在计算机中&…...

快速安装Arduino IED的STM32 MCU开发包

从github安装STM32 MCU开发包非常慢&#xff0c;很难安装成功。因此我将Arduino IED的TM32 MCU开发包上传到国内网站&#xff0c;亲测安装成功。 1.打开Arduino IED&#xff0c;文件--首选项--其它开发板管理地址&#xff0c;添加http://www.aluoyun.cn/BoardManagerFiles-mai…...

Html 2

一&#xff0c;表单 1.概念&#xff1a;在一个区域中&#xff0c;拥有许多输入和最终组件&#xff0c;可以让用户输入、选择信息&#xff0c;最终将信息传入服务器端 2.常用组件&#xff1a; &#xff08;1&#xff09;<form action " " methon "get&qu…...

业务层在事务中高频创建动态表然后删除或者回滚导致 pg_dump 概率出现备份失败问题分析

文章目录 测试环境&#xff0c;业务层在事务中高频创建动态表然后删除或者回滚导致 pg_dump 概率出现备份失败职责划分​​应用层对 DDL 事务的滥用​​ 导致的目录污染怎么理解&#xff1f;应用层在事务中大量高频新建动态表&#xff0c; 然后删除表, 有啥隐患​​目录版本风暴…...

图漾官网Sample_V1版本C++语言完整参考例子---单相机版本

文章目录 1.参考例子 主要梳理了图漾官网Sample_V1版本的例子 1.参考例子 主要增加了从storage区域读取相机参数的设置&#xff0c;使用图漾PercipioViewer软件&#xff0c;如何将相机参数保存到srorage区&#xff0c;可参考链接&#xff1a;保存相机参数操作 保存参数设置 注…...

SSM书籍管理(业务编写)

查询书籍功能 编写Controller类 Controller RequestMapping("/book") public class BookController {//controller调用service层AutowiredQualifier("BookServiceImpl")private BookService bookService;//查询全部的书籍&#xff0c;并且返回到书籍展示…...

kafka消息的顺序性如何保持一致的

目录 背景&#xff1a; 原理&#xff1a; 情况一&#xff1a;如果只有一个分区 情况二&#xff1a;如果有多个分区 总结 背景&#xff1a; 最近面试总是被问这个问题&#xff0c;然后总感觉答得不好就写博客总结一下&#xff0c;可以先看总结 原理&#xff1a; Kafka 中&#…...

在Java中基于Geotools对PostGIS数据库的空间查询实践

目录 前言 一、相关技术背景介绍 1、评价对象AOI 2、数据处理流程 二、对AOI空间范围查询实践 1、空间查询构建 2、空间样式创建 3、成果出图 三、总结 前言 在当今数字化浪潮下&#xff0c;空间数据的应用价值日益凸显&#xff0c;从城市规划到环境监测&#xff0c;从…...

生活需要一些思考

总分总 写文章、做事情、写邮件、写信&#xff0c;都是要【总分总】。 先总【因为没人有耐心一上来就看细节&#xff0c;先总结&#xff0c;别人感兴趣才会看分】 然后分【分中包括多个子部分&#xff0c;或子章节、子目标&#xff0c;他们之间层层递进&#xff0c;最终引出最…...

Scrapy框架之CrawlSpider爬虫 实战 详解

CrawlSpider 是 Scrapy 框架中一个非常实用的爬虫基类&#xff0c;它继承自 Spider 类&#xff0c;主要用于实现基于规则的网页爬取。相较于普通的 Spider 类&#xff0c;CrawlSpider 可以根据预定义的规则自动跟进页面中的链接&#xff0c;从而实现更高效、更灵活的爬取。 Scr…...

DeepSeek主动学习系统:低质量数据炼金术的工程化实践

文章目录 一、技术体系架构升级1.1 四层协同系统架构1.2 关键技术组件解析(1) 跨模态特征对齐引擎(2) 动态采样策略库 二、低质量数据治理全流程2.1 数据清洗与增强流水线2.2 主动学习迭代流程 三、工业级部署方案3.1 分布式计算架构3.2 动态环境应对策略(1) 概念漂移检测(2) 持…...

学习记录:DAY20

技术探索之旅&#xff1a;YAML配置&#xff0c;依赖注入、控制反转与Java注解 前言 最近有点懒了&#xff0c;太松懈可不行。为了让自己保持学习的动力&#xff0c;我决定将最近的学习内容整理成博客&#xff0c;目标是让未来的自己也能轻松理解。我会尽量以整体记录的方式呈…...

[AI]browser-use + web-ui 大模型实现自动操作浏览器

[AI]browser-use web-ui 大模型实现自动操作浏览器 介绍 官方地址&#xff1a;https://github.com/browser-use/web-ui browser-use主要作用是将 AI Agent 与浏览器链接起来从而实现由 AI 驱动的浏览器自动化。今天会给大家介绍如何通过browser-use web-ui来搭建并操作browse…...

使用LangChain连接远程Oracle数据库尝试LLM 提供的SQL智能助理

使用LangChain连接远程Oracle数据库尝试LLM 提供的SQL智能助理 为完成此次数据库连接实验&#xff0c;笔者用自己的笔记本电脑搭建了一台linux虚机&#xff0c;安装了oracle 23C&#xff0c;并借助deepseek创建了若干与电商业务有关的表并插入了一些记录。 接着在windows实体…...

训练神经网络的批量标准化(使用 PyTorch)

构建神经网络是一门艺术&#xff0c;而非一个结果固定的过程。你无法预知最终能否得到有效的模型&#xff0c;而且有很多因素可能导致你的机器学习项目失败。 然而&#xff0c;随着时间的推移&#xff0c;您还将学会一套特定的笔触&#xff0c;这将大大提高您成功的几率。 在…...

阿里Qwen3 8款模型全面开源,免费商用,成本仅为 DeepSeek-R1 的三分之一

想要掌握如何将大模型的力量发挥到极致吗&#xff1f;叶梓老师带您深入了解 Llama Factory —— 一款革命性的大模型微调工具&#xff08;限时免费&#xff09;。 1小时实战课程&#xff0c;您将学习到如何轻松上手并有效利用 Llama Factory 来微调您的模型&#xff0c;以发挥其…...

Vue常用的修饰符有哪些有什么应用场景(含deep seek讲解)

Vue.js 事件修饰符的功能与具体应用场景 一、事件修饰符 .stop .stop 的主要作用是 阻止事件冒泡&#xff0c;防止事件从子元素传播到父元素。这在处理嵌套组件或多层 DOM 结构时非常有用。 <div click"parentClick">Parent<button click.stop"chi…...