JVM知识点(2)

目录

Java中可作为GC Roots的引用有哪几种?

finalize方法

垃圾回收算法

标记-清除

标记-复制

标记-整理

分代收集算法

为什么要用分代收集

标记复制的标记过程和复制会不会停顿

MinorGC,MajorGC,MixedGC,FullGC

FullGC怎么清理

什么时候触发FullGC

空间分配担保是什么

垃圾收集器

Serial收集器

Serial收集器是最基础,历史最悠久的收集器

ParNew收集器

Parallerl Scavenge收集器

SerialOld收集器

Parallel Old收集器

CMS收集器

G1收集器

ZGC收集器

 

垃圾回收器的作用

CMS

重新标记

什么是三色标记

G1

CMS,G1

如何选择垃圾收集器

JVM调优

jmap

可视化的性能监控工具

第三方工具

JVM常见参数

堆内存

GC收集器

JVM调优

CPU内存过高怎么排查

内存飙高问题怎么排查

频繁的minroGc怎么办

频繁FUllGC

怎么排查

类加载机制

类加载机制

类的生命周期

类装载的过程

双亲委派

 为什么使用双亲委派

破坏双亲委派

解释执行和编译执行的区别

Java中可作为GC Roots的引用有哪几种?

所谓的GC Roots,就是一组必须活跃的引用,它们是程序运行时的起点,是一切引用链的源头。在Java中,GC Roots包括以下几种:

  • 虚拟机栈中的引用(方法的参数、局部变量等)
  • 本地方法栈中 JNI 的引用
  • 类静态变量
  • 运行时常量池中的常量(String 或 Class 类型)

finalize方法

如果对象在进行可达性分析后发现没有与 GC Roots 相连接的引用链,那它将会被第一次标记,随后进行一次筛选。

筛选的条件是对象是否有必要执行 finalize()方法。

如果对象在 finalize() 中成功拯救自己——只要重新与引用链上的任何一个对象建立关联即可。

譬如把自己 (this 关键字)赋值给某个类变量或者对象的成员变量,那在第二次标记时它就”逃过一劫“;但是如果没有抓住这个机会,那么对象就真的要被回收了。

垃圾回收算法

垃圾收集算法主要是三种:

分别是标记-清除算法、标记-复制算法和标记-整理算法。

标记-清除

标记-清除算法分为两个阶段:

  • 标记:标记所有需要回收的对象
  • 清除:回收所有被标记的对象
  • 优点是实现简单,缺点是回收过程中会产生内存碎片。
标记-复制

标记-复制算法可以解决标记-清除算法的内存碎片问题,因为它将内存空间划分为两块,每次只使用其中一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后清理掉这一块。

缺点是浪费了一半的内存空间。

标记-整理

标记-整理算法是标记-清除复制算法的升级版,它不再划分内存空间,而是将存活的对象向内存的一端移动,然后清理边界以外的内存。

缺点是移动对象的成本比较高。

分代收集算法

分代收集算法是目前主流的垃圾收集算法,它根据对象存活周期的不同将内存划分为几块,一般分为新生代和老年代。

新生代用复制算法,因为大部分对象生命周期短。老年代用标记-整理算法,因为对象存活率较高。

为什么要用分代收集

分代收集算法的核心思想是根据对象的生命周期优化垃圾回收。

新生代的对象生命周期短,使用复制算法可以快速回收。老年代的对象生命周期长,使用标记-整理算法可以减少移动对象的成本。

标记复制的标记过程和复制会不会停顿

在标记-复制算法 中,标记阶段和复制阶段都会触发STW。

  • 标记阶段停顿是为了保证对象的引用关系不被修改。
  • 复制阶段停顿是防止对象在复制过程中被修改。

MinorGC,MajorGC,MixedGC,FullGC

Minor GC 也称为 Young GC,是指发生在年轻代的垃圾收集。年轻代包含 Eden 区以及两个 Survivor 区。

Major GC 也称为 Old GC,主要指的是发生在老年代的垃圾收集。是 CMS 的特有行为。

Mixed GC 是 G1 垃圾收集器特有的一种 GC 类型,它在一次 GC 中同时清理年轻代和部分老年代。

Full GC 是最彻底的垃圾收集,涉及整个 Java 堆和方法区。它是最耗时的 GC,通常在 JVM 压力很大时发生。

FullGC怎么清理

Full GC 会从 GC Root 出发,标记所有可达对象。新生代使用复制算法,清空 Eden 区。老年代使用标记-整理算法,回收对象并消除碎片。

什么时候触发FullGC

在进行 Young GC 的时候,如果发现老年代可用的连续内存空间 < 新生代历次 Young GC 后升入老年代的对象总和的平均大小,说明本次 Young GC 后升入老年代的对象大小,可能超过了老年代当前可用的内存空间,就会触发 Full GC。

执行 Young GC 后老年代没有足够的内存空间存放转入的对象,会立即触发一次 Full GC。

空间分配担保是什么

空间分配担保是指在进行 Minor GC 前,JVM 会确保老年代有足够的空间存放从新生代晋升的对象。如果老年代空间不足,可能会触发 Full GC。

垃圾收集器

JVM 的垃圾收集器主要分为两大类:分代收集器和分区收集器,分代收集器的代表是 CMS,分区收集器的代表是 G1 和 ZGC。

CMS 是第一个关注 GC 停顿时间的垃圾收集器,JDK 1.5 时引入,JDK9 被标记弃用,JDK14 被移除。

G1 在 JDK 1.7 时引入,在 JDK 9 时取代 CMS 成为了默认的垃圾收集器。

ZGC 是 JDK11 推出的一款低延迟垃圾收集器,适用于大内存低延迟服务的内存管理和回收,在 128G 的大堆下,最大停顿时间才 1.68 ms,性能远胜于 G1 和 CMS。

Serial收集器

Serial收集器是最基础,历史最悠久的收集器

如同它的名字(串行),它是一个单线程工作的收集器,使用一个处理器或一条收集线程去完成垃圾收集工作。并且进行垃圾收集时,必须暂停其他所有工作线程,直到垃圾收集结束——这就是所谓的“Stop The World”。

ParNew收集器

ParNew收集器实质上是Serial收集器的多线程并发版本,使用多条线程进行垃圾收集。

 

Parallerl Scavenge收集器

Paraller Scabenge收集器是一款新生代收集器,基于标记复制算法实现,也能够并行收集。和 ParNew 有些类似,但 Parallel Scavenge 主要关注的是垃圾收集的吞吐量——所谓吞吐量,就是 CPU 用于运行用户代码的时间和总消耗时间的比值,比值越大,说明垃圾收集的占比越小。

SerialOld收集器

 Serial Old 是 Serial 收集器的老年代版本,它同样是一个单线程收集器,使用标记-整理算法。

Parallel Old收集器

Parallel Old是Parallel Scavenge 收集器的老年代版本,基于标记-整理算法实现,使用多条 GC 线程在 STW 期间同时进行垃圾回收。

CMS收集器

CMS 是一种低延迟的垃圾收集器,采用标记-清除算法,分为初始标记、并发标记、重新标记和并发清除四个阶段,优点是垃圾回收线程和应用线程同时运行,停顿时间短,适合延迟敏感的应用,但容易产生内存碎片,可能触发 Full GC。

G1收集器

G1 在 JDK 1.7 时引入,在 JDK 9 时取代 CMS 成为默认的垃圾收集器。

G1 是一种面向大内存、高吞吐场景的垃圾收集器,它将堆划分为多个小的 Region,通过标记-整理算法,避免了内存碎片问题。优点是停顿时间可控,适合大堆场景,但调优较复杂。

ZGC收集器
 

ZGC 是 JDK 11 时引入的一款低延迟的垃圾收集器,最大特点是将垃圾收集的停顿时间控制在 10ms 以内,即使在 TB 级别的堆内存下也能保持较低的停顿时间。

它通过并发标记和重定位来避免大部分 Stop-The-World 停顿,主要依赖指针染色来管理对象状态。

  • 标记对象的可达性:通过在指针上增加标记位,不需要额外的标记位即可判断对象的存活状态。
  • 重定位状态:在对象被移动时,可以通过指针染色来更新对象的引用,而不需要等待全局同步。

适用于需要超低延迟的场景,比如金融交易系统、电商平台。

垃圾回收器的作用

垃圾回收器的核心作用是自动管理 Java 应用程序的运行时内存。它负责识别哪些内存是不再被应用程序使用的,并释放这些内存以便重新使用。

这一过程减少了程序员手动管理内存的负担,降低了内存泄漏和溢出错误的风险。

CMS

CMS 使用标记-清除算法进行垃圾收集,分 4 大步:

  • 初始标记:标记所有从 GC Roots 直接可达的对象,这个阶段需要 STW,但速度很快。
  • 并发标记:从初始标记的对象出发,遍历所有对象,标记所有可达的对象。这个阶段是并发进行的。
  • 重新标记:完成剩余的标记工作,包括处理并发阶段遗留下来的少量变动,这个阶段通常需要短暂的 STW 停顿。
  • 并发清除:清除未被标记的对象,回收它们占用的内存空间。

重新标记

remark阶段,通常结合三色标记法来执行。确保在并发标记期间所有存活对象都被正确标记。目的是修正并发标记阶段中可能遗漏的对象引用变化。

什么是三色标记

 

三色标记法用于标记对象的存活状态,它将对象分为三类:

  1. 白色(White):尚未访问的对象。垃圾回收结束后,仍然为白色的对象会被认为是不可达的对象,可以回收。
  2. 灰色(Gray):已经访问到但未标记完其引用的对象。灰色对象是需要进一步处理的。
  3. 黑色(Black):已经访问到并且其所有引用对象都已经标记过。黑色对象是完全处理过的,不需要再处理。

三色标记法的工作流程:

①、初始标记(Initial Marking):从 GC Roots 开始,标记所有直接可达的对象为灰色。

②、并发标记(Concurrent Marking):在此阶段,标记所有灰色对象引用的对象为灰色,然后将灰色对象自身标记为黑色。这个过程是并发的,和应用线程同时进行。

此阶段的一个问题是,应用线程可能在并发标记期间修改对象的引用关系,导致一些对象的标记状态不准确。

③、重新标记(Remarking):重新标记阶段的目标是处理并发标记阶段遗漏的引用变化。为了确保所有存活对象都被正确标记,remark 需要在 STW 暂停期间执行。

④、使用写屏障(Write Barrier)来捕捉并发标记阶段应用线程对对象引用的更新。通过遍历这些更新的引用来修正标记状态,确保遗漏的对象不会被错误地回收。

G1

G1 把 Java 堆划分为多个大小相等的独立区域Region,每个区域都可以扮演新生代或老年代的角色。

这种区域化管理使得 G1 可以更灵活地进行垃圾收集,只回收部分区域而不是整个新生代或老年代。

①、并发标记,G1 通过并发标记的方式找出堆中的垃圾对象。并发标记阶段与应用线程同时执行,不会导致应用线程暂停。

②、混合收集,在并发标记完成后,G1 会计算出哪些区域的回收价值最高(也就是包含最多垃圾的区域),然后优先回收这些区域。这种回收方式包括了部分新生代区域和老年代区域。

选择回收成本低而收益高的区域进行回收,可以提高回收效率和减少停顿时间。

③、可预测的停顿,G1 在垃圾回收期间仍然需要「Stop the World」。不过,G1 在停顿时间上添加了预测机制,用户可以 JVM 启动时指定期望停顿时间,G1 会尽可能地在这个时间内完成垃圾回收。

CMS,G1

特性CMSG1
设计目标低停顿时间可预测的停顿时间
并发性
内存碎片是,容易产生碎片否,通过区域划分和压缩减少碎片
收集代数年轻代和老年代整个堆,但区分年轻代和老年代
并发阶段并发标记、并发清理并发标记、并发清理、并发回收
停顿时间预测较难预测可配置停顿时间目标
容易出现的问题内存碎片、Concurrent Mode Failure较少出现长时间停顿

CMS 适用于对延迟敏感的应用场景,主要目标是减少停顿时间,但容易产生内存碎片。

G1 则提供了更好的停顿时间预测和内存压缩能力,适用于大内存和多核处理器环境。

如何选择垃圾收集器

如果应用程序只需要一个很小的内存空间(大约 100 MB),或者对停顿时间没有特殊的要求,可以选择 Serial 收集器。

如果优先考虑应用程序的峰值性能,并且没有时间要求,或者可以接受 1 秒或更长的停顿时间,可以选择 Parallel 收集器。

如果响应时间比吞吐量优先级高,或者垃圾收集暂停必须保持在大约 1 秒以内,可以选择 CMS/ G1 收集器。

如果响应时间是高优先级的,或者堆空间比较大,可以选择 ZGC 收集器。

JVM调优

操作系统层面,我用过 top、vmstat、iostat、netstat 等命令,可以监控系统整体的资源使用情况,比如说内存、CPU、IO 使用情况、网络使用情况。

JDK 自带的命令行工具层面,我用过 jps、jstat、jinfo、jmap、jhat、jstack、jcmd 等,可以查看 JVM 运行时信息、内存使用情况、堆栈信息等。

jmap

①、我一般会使用 jmap -heap <pid> 查看堆内存摘要,包括新生代、老年代、元空间等。

②、或者使用 jmap -histo <pid> 查看对象分布。

③、还有生成堆转储文件:jmap -dump:format=b,file=<path> <pid>

可视化的性能监控工具

①、JConsole:JDK 自带的监控工具,可以用来监视 Java 应用程序的运行状态,包括内存使用、线程状态、类加载、GC 等。

②、VisualVM:一个基于 NetBeans 的可视化工具,在很长一段时间内,VisualVM 都是 Oracle 官方主推的故障处理工具。集成了多个 JDK 命令行工具的功能,非常友好。

③、Java Mission Control:JMC 最初是 JRockit VM 中的诊断工具,但在 Oracle JDK7 Update 40 以后,就绑定到了 HotSpot VM 中。不过后来又被 Oracle 开源出来作为了一个单独的产品。

第三方工具

MAT,GChisto

JVM常见参数

堆内存

  • -Xms:初始堆大小
  • -Xmx:最大堆大小
  • -XX:NewSize=n:设置年轻代大小
  • -XX:NewRatio=n:设置年轻代和年老代的比值。如:n 为 3 表示年轻代和年老代比值为 1:3,年轻代占总和的 1/4
  • -XX:SurvivorRatio=n:年轻代中 Eden 区与两个 Survivor 区的比值。如 n=3 表示 Eden 占 3 Survivor 占 2,一个 Survivor 区占整个年轻代的 1/5

GC收集器

  • -XX:+UseSerialGC:设置串行收集器
  • -XX:+UseParallelGC:设置并行收集器
  • -XX:+UseParalledlOldGC:设置并行老年代收集器
  • -XX:+UseConcMarkSweepGC:设置并发收集器

JVM调优

JVM 调优是一个复杂的过程,调优的对象包括堆内存、垃圾收集器和 JVM 运行时参数等。

 如果堆内存设置过小,可能会导致频繁的垃圾回收。

在项目运行期间,我会使用 JVisualVM 定期观察和分析 GC 日志,如果发现频繁的 Full GC,我会特意关注一下老年代的使用情况。

接着,通过分析 Heap dump 寻找内存泄漏的源头,看看是否有未关闭的资源,长生命周期的大对象等。

之后进行代码优化,比如说减少大对象的创建、优化数据结构的使用方式、减少不必要的对象持有等。

CPU内存过高怎么排查

首先使用top命令观看CPU占用情况

接着使用jstack命令查看对应进程的线程堆栈信息

然后再使用 top 命令查看进程中线程的占用情况,找到占用 CPU 较高的线程 ID。

top 命令显示的线程 ID 是十进制的,而 jstack 输出的是十六进制的,所以需要将线程 ID 转换为十六进制。

 jstack 的输出中搜索这个十六进制的线程 ID,找到对应的堆栈信息。

最后,根据堆栈信息定位到具体的业务方法,查看是否有死循环、频繁的垃圾回收、资源竞争导致的上下文频繁切换等问题。

内存飙高问题怎么排查

内存飚高一般是因为创建了大量的 Java 对象导致的,如果持续飙高则说明垃圾回收跟不上对象创建的速度,或者内存泄漏导致对象无法回收。

第一,先观察垃圾回收的情况,可以通过 jstat -gc PID 1000 查看 GC 次数和时间。

第二步,通过 jmap 命令 dump 出堆内存信息。

第三步,使用可视化工具分析 dump 文件,比如说 VisualVM,找到占用内存高的对象,再找到创建该对象的业务代码位置,从代码和业务场景中定位具体问题。

频繁的minroGc怎么办

频繁的 Minor GC 通常意味着新生代中的对象频繁地被垃圾回收,可能是因为新生代空间设置的过小,或者是因为程序中存在大量的短生命周期对象(如临时变量)。

可以使用 GC 日志进行分析,查看 GC 的频率和耗时,找到频繁 GC 的原因。

或者使用监控工具查看堆内存的使用情况,特别是新生代(Eden 和 Survivor 区)的使用情况。

如果是因为新生代空间不足,可以通过 -Xmn 增加新生代的大小,减缓新生代的填满速度。

如果对象需要长期存活,但频繁从 Survivor 区晋升到老年代,可以通过 -XX:SurvivorRatio 参数调整 Eden 和 Survivor 的比例。默认比例是 8:1,表示 8 个空间用于 Eden,1 个空间用于 Survivor 区。调整为 6 的话,会减少 Eden 区的大小,增加 Survivor 区的大小,以确保对象在 Survivor 区中存活的时间足够长,避免过早晋升到老年代。

频繁FUllGC

频繁的 Full GC 通常意味着老年代中的对象频繁地被垃圾回收,可能是因为老年代空间设置的过小,或者是因为程序中存在大量的长生命周期对象。

怎么排查

过专门的性能监控系统,查看 GC 的频率和堆内存的使用情况,然后根据监控数据分析 GC 的原因。

或者:我一般会使用 JDK 的自带工具,包括 jmap、jstat 等。

或者使用一些可视化的工具,比如 VisualVM、JConsole 等,查看堆内存的使用情况。

假如是因为大对象直接分配到老年代导致的 Full GC 频繁,可以通过 -XX:PretenureSizeThreshold 参数设置大对象直接进入老年代的阈值。

或者将大对象拆分成小对象,减少大对象的创建。比如说分页。

假如是因为内存泄漏导致的频繁 Full GC,可以通过分析堆内存 dump 文件找到内存泄漏的对象,再找到内存泄漏的代码位置。

假如是因为长生命周期的对象进入到了老年代,要及时释放资源,比如说 ThreadLocal、数据库连接、IO 资源等。

假如是因为 GC 参数配置不合理导致的频繁 Full GC,可以通过调整 GC 参数来优化 GC 行为。或者直接更换更适合的 GC 收集器,如 G1、ZGC 等。

类加载机制

类加载机制

JVM 的操作对象是 Class 文件,JVM 把 Class 文件中描述类的数据结构加载到内存中,并对数据进行校验、解析和初始化,最终转化成可以被 JVM 直接使用的类型,这个过程被称为类加载机制。

  • 类加载器:负责加载类文件,将类文件加载到内存中,生成 Class 对象。
  • 类加载过程:包括加载、验证、准备、解析和初始化等步骤。
  • 双亲委派模型:当一个类加载器接收到类加载请求时,它会把请求委派给父——类加载器去完成,依次递归,直到最顶层的类加载器,如果父——类加载器无法完成加载请求,子类加载器才会尝试自己去加载。

类的生命周期

一个类从被加载到虚拟机内存中开始,到从内存中卸载,整个生命周期需要经过七个阶段:加载 、验证、准备、解析、初始化、使用和卸载。
 

类装载的过程

类装载过程包括三个阶段:载入、链接和初始化。

①、载入:将类的二进制字节码加载到内存中。

②、链接可以细分为三个小的阶段:

  • 验证:检查类文件格式是否符合 JVM 规范
  • 准备:为类的静态变量分配内存并设置默认值。
  • 解析:将符号引用替换为直接引用。

③、初始化:执行静态代码块和静态变量初始化。

双亲委派

双亲委派模型要求类加载器在加载类时,先委托父加载器尝试加载,只有父加载器无法加载时,子加载器才会加载。

 为什么使用双亲委派

①、避免类的重复加载:父加载器加载的类,子加载器无需重复加载。

②、保证核心类库的安全性:如 java.lang.* 只能由 Bootstrap ClassLoader 加载,防止被篡改。

破坏双亲委派

重写 ClassLoader 的 loadClass() 方法。

解释执行和编译执行的区别

  • 解释:将源代码逐行转换为机器码。
  • 编译:将源代码一次性转换为机器码。

一个是逐行,一个是一次性,再来说说解释执行和编译执行的区别:

  • 解释执行:程序运行时,将源代码逐行转换为机器码,然后执行。
  • 编译执行:程序运行前,将源代码一次性转换为机器码,然后执行。

但 JIT 的出现打破了这种刻板印象,JVM 会将热点代码(即运行频率高的代码)编译后放入 CodeCache,当下次执行再遇到这段代码时,会从 CodeCache 中直接读取机器码,然后执行。

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

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

相关文章

Java HashMap中的compute及相关方法详解:从基础到Kafka Stream应用

HashMap是Java集合框架中最常用的数据结构之一&#xff0c;它提供了高效的键值对存储和检索功能。在Java8中&#xff0c;HashMap引入了一系列新的原子性更新方法&#xff0c;包括compute()、computeIfAbsent()和computeIfPresent()等&#xff0c;这些方法极大地简化了在Map中进…

【php中ssti模板注入讲解】

php中场景模板 1. Smarty 使用安全模式来执行不信任的模板,只运行PHP白名单里的函数。 2. Twig 与Smarty类似,不过无法利用该模板的SSTI调用静函数。 php常见模板入门 Smarty 不使用预先准备好的模板 使用预先准备好的模板 对值进行拼接后使用模板展示 设置在模板中…

Redis学习07-Redis的过期策略

Redis 过期策略 什么是过期策略 Redis 的过期策略用于管理设置了过期时间&#xff08;TTL&#xff09;的键&#xff0c;确保在键过期后能够被及时删除&#xff0c;从而释放内存 整体策略 Redis 采用的是定期删除惰性删除的组合策略 1. 定期删除 原理&#xff1a;周期性的从过期…

深入解读c++(命名空间)

目录 1关于命名空间 1.1是什么 1.2解决了什么问题 2.命名空间的定义 2.2命名空间的嵌套定义 3命名空间的特点 3.1命名空间不会影响生命周期 3.2命名空间只能在全局域里定义&#xff0c;当然嵌套定义时例外。 3.3在不同文件中定义相同名称的命名空间 4.命名空间的使用 …

ClickHouse高性能实时分析数据库-高性能的模式设计

告别等待&#xff0c;秒级响应&#xff01;这不只是教程&#xff0c;这是你驾驭PB级数据的超能力&#xff01;我的ClickHouse视频课&#xff0c;凝练十年实战精华&#xff0c;从入门到精通&#xff0c;从单机到集群。点开它&#xff0c;让数据处理速度快到飞起&#xff0c;让你…

ArkTS懒加载LazyForEach的基本使用

在 ArkTS 的开发中&#xff0c;如果你要渲染一个很长的列表&#xff0c;比如商品列表、评论列表或者朋友圈动态&#xff0c;用传统的循环结构&#xff08;比如 ForEach&#xff09;很容易导致性能问题&#xff0c;尤其是加载慢、卡顿甚至内存暴涨。 这时候就要用到 懒加载渲染组…

动态规划:从入门到精通

本文全章节一共一万七千多字&#xff0c;详细介绍动态规划基础与进阶技巧&#xff0c;全篇以代码为主&#xff0c;认真读完理解&#xff0c;你对动态规划的理解一定会有一个质的飞跃。一、动态规划简介: 动态规划&#xff08;Dynamic Programming&#xff0c;简称DP&…

八股训练营 40 天心得:一场结束,也是一场新的开始

八股训练营 40 天心得&#xff1a;一场结束&#xff0c;也是一场新的开始 感谢卡哥的训练营组织卡码笔记&#xff0c;对即将参加秋招的我们帮助了很多&#xff0c;感谢卡哥的开源代码随想录代码随想录 四十天前&#xff0c;我带着一颗不安却坚定的心&#xff0c;踏入了这场“…

STM32系统定时器(SysTick)详解:从原理到实战的精确延时与任务调度

前言&#xff1a;为什么SysTick是嵌入式开发的"瑞士军刀"&#xff1f; 在STM32开发中&#xff0c;我们经常需要精确的延时功能&#xff08;如毫秒级延时控制LED闪烁&#xff09;或周期性任务调度&#xff08;如定时采集传感器数据&#xff09;。实现这些功能的方式有…

【微信小程序】12、生物认证能力

1、生物认证 生物认证 是一种基于个体独特生理或行为特征进行身份验证的技术,广泛应用于安全、金融、医疗等领域。 小程序目前暂时只支持指纹识别认证。 2、查询支持的生物认证方式 获取本机支持的 SOTER 生物认证方式&#xff0c;文档 onLoad(options) {wx.checkIsSuppor…

高级机器学习

机器学习常见方法涉及方法&#xff1a;2.半监督学习3.无监督学习4.度量学习5.迁移学习6.多示例多标记学习7.在线学习8.元学习9.联邦学习10.强化学习11.概率图模型独立同分布独立指的是&#xff0c;样本集包括训练集测试集的任意两个样本之间都是不相关的。在表示样本的特征确定…

Chrome 提示 “此扩展程序不再受支持”(MacOS/Windows)

原因 最新 Chrome 使用 Manifest V3, 并在新版浏览器中 停止 V2 支持 处理方法 MacOS 新建一个后缀为 .mobileconfig 的文件, 内容参考 <?xml version"1.0" encoding"UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN&…

C++20协程实战:高效网络库、手机终端、多媒体开发开发指南

基于C++协程和事件循环的网络库 以下是基于C++协程和事件循环的网络库实例,涵盖常见场景和功能实现。示例基于libuv、Boost.Asio或自定义事件循环,结合C++20协程(如std::coroutine)或其他协程库(如cppcoro)实现。 基础TCP服务器 #include <cppcoro/task.hpp> #in…

数据库4.0

索引 事务 JDBC~ 目录 一、MySQL索引 1.0 概述 2.0 相关操作 3.0 注意 4.0 索引背后的原理的理解 二、 事务 1.0 原子性 2.0 隔离性 (1)并发执行 (2) 出现的问题 3.0 使用 三、JDBC编程 1.0 概述 2.0 如何下载驱动包 3.0 jar如何引入到项目之中 4.0 jdbc…

HarmonyOS-ArkUI Web控件基础铺垫6--TCP协议- 流量控制算法与拥塞控制算法

HarmonyOS-ArkUI Web控件基础铺垫1-HTTP协议-数据包内容-CSDN博客 HarmonyOS-ArkUI Web控件基础铺垫2-DNS解析-CSDN博客 HarmonyOS-ArkUI Web控件基础铺垫3--TCP协议- 从规则本质到三次握手-CSDN博客 HarmonyOS-ArkUI Web控件基础铺垫4--TCP协议- 断联-四次挥手解析-CSDN博客…

Dify 从入门到精通(2/100 篇):Dify 的核心组件 —— 从节点到 RAG 管道

Dify 的核心组件&#xff1a;从节点到 RAG 管道 引言 在 Dify 博客系列&#xff1a;从入门到精通&#xff08;100 篇&#xff09; 的第一篇《Dify 究竟是什么&#xff1f;真能开启低代码 AI 应用开发的未来&#xff1f;》中&#xff0c;我们全面介绍了 Dify 的定位、核心特点…

在线培训、远程示教——医疗器械行业的直播解决方案

文章目录前言一、医疗器械直播应用的两大核心场景二、直播平台在医疗场景中的关键技术支持点三、典型功能实现原理总结前言 医疗器械行业对“培训”和“示教”的专业性要求极高&#xff0c;传统的线下模式常因时间、空间、人员成本等受限而效率低下。而随着高清低延迟视频技术…

Mqttnet的MqttClientTlsOptions.CertificateValidationHandler详解

MqttClientTlsOptions.CertificateValidationHandler 是 MQTTnet 库中用于自定义 TLS 证书验证逻辑的关键回调函数。在 MQTT 客户端与服务器建立 TLS 连接时&#xff0c;该回调允许你覆盖默认的证书验证流程&#xff0c;实现自定义的安全策略。核心作用当 MQTT 客户端通过 TLS …

【图像噪点消除】——图像预处理(OpenCV)

目录 1 均值滤波 2 方框滤波 3 高斯滤波 4 中值滤波 5 双边滤波 6 小结 噪声&#xff1a;图像中的一些干扰因素。通常是由于图像采集设备、传输信道等因素造成的&#xff0c;表现为图像中随机的亮度。常见的噪声类型有高斯噪声和椒盐噪声。高斯噪声是一种分布符合正态分布…

Vulnhub napping-1.0.1靶机渗透攻略详解

一、下载靶机 下载地址&#xff1a;https://download.vulnhub.com/napping/napping-1.0.1.ova 下载好后使用VM打开&#xff0c;将网络配置模式改为net&#xff0c;防止桥接其他主机干扰&#xff08;桥接Mac地址也可确定主机&#xff09;。 二、发现主机 使用nmap扫描没有相应…