1. 引言

1.1 为什么需要垃圾收集?

在Java应用中,垃圾收集(Garbage Collection,GC)是一个至关重要的机制,它使得开发者不需要手动管理内存。与传统的语言(如C或C++)不同,Java通过自动垃圾收集机制来释放不再使用的对象,从而避免了内存泄漏和悬空指针等问题。现代应用的复杂性日益增加,程序员不再仅仅关注应用的业务逻辑,还必须考虑内存的管理,尤其是如何高效地管理大量的对象和内存。

垃圾收集的核心目标是:

  • 自动内存管理:开发者无需手动管理内存的分配与回收,减少人为错误。

  • 避免内存泄漏:及时清理不再使用的对象,释放内存。

  • 提升应用性能:通过有效的垃圾收集机制,减少内存占用,提升程序的执行效率。

在Java中,GC不仅仅是一个内存回收的过程,它的实现与算法的选择直接影响到程序的性能。不同的垃圾收集算法对CPU、内存和响应时间的影响各不相同,因此理解GC的原理与机制是优化Java应用性能的关键。

1.2 Java中的垃圾收集机制概述

Java的垃圾收集机制并非一成不变,它随着JVM版本的不同,采用了多种不同的收集算法和策略。Java 8版本的垃圾收集机制相较于早期的版本进行了较大的优化,特别是在引入新的垃圾收集器(如G1)后,GC的性能得到了显著提升。

Java的垃圾收集机制主要基于以下几个关键概念:

  • 堆(Heap):JVM堆是所有对象实例的内存区域。垃圾收集器主要负责回收堆中的对象。

  • 分代收集(Generational Collection):Java中的堆被分为多个区域(年轻代、老年代、永久代/元空间),不同代的对象使用不同的回收策略。这种分代设计是Java垃圾收集性能优化的关键。

  • 垃圾收集器(GC):JVM提供了多种垃圾收集器,每种收集器有不同的特点和适用场景。Java 8中,最常用的垃圾收集器包括Serial、Parallel、CMS和G1。

垃圾收集器的选择和调优是Java性能优化的一个重要课题,选择一个合适的垃圾收集器可以显著提高程序的响应速度和吞吐量。

1.3 本文结构

本文将详细介绍Java 8中垃圾收集的机制,包括常见的垃圾收集算法、各个垃圾收集器的特点及其在不同场景下的应用。通过阅读本文,读者将能够:

  • 理解分代收集理论和垃圾收集的基本原理;

  • 掌握常见垃圾收集算法(如标记-清除、标记-复制、标记-整理等);

  • 学习如何根据实际需求选择和调优垃圾收集器;

  • 掌握JVM的垃圾收集器(Serial、Parallel、CMS、G1)的配置与优化技巧。

接下来的章节将深入探讨每种垃圾收集算法的原理与Java 8的具体实现,帮助开发者更好地理解和利用Java中的垃圾收集机制,进而提升应用的性能。

2. 分代收集理论

2.1 分代收集的背景

分代收集(Generational Collection)理论是Java垃圾收集机制的核心理念之一。该理论的提出源自对内存回收效率的优化需求。根据“年轻对象存活较短,老对象存活较长”的观察,垃圾收集器可以对内存中的对象进行分代管理,不同代使用不同的回收策略,从而提高垃圾收集的效率。

在没有分代收集理论之前,所有对象都被视为“平等的”,每个对象都在同样的方式下进行回收。然而,现实中我们发现,许多短生命周期的对象(如临时变量、局部对象等)很快变为垃圾,而一些长期存在的对象(如缓存、静态变量等)则存活较长时间。由于对象生命周期的差异,使用统一的回收策略效率较低。

分代收集理论将内存划分为不同的区域(或“代”),根据对象的年龄(存活时间)来选择合适的垃圾回收策略。Java中的堆内存(Heap)被划分为三个主要部分:年轻代(Young Generation)、老年代(Old Generation)和永久代(PermGen,Java 8中已替代为元空间Metaspace)。

2.2 分代收集的具体原理

分代收集的基本思想是:根据对象的生命周期将对象划分为不同的代,并且对不同代的对象使用不同的垃圾收集算法。

  1. 年轻代(Young Generation)
    年轻代用于存储新创建的对象。大多数新对象在这里创建并且很快变为垃圾。年轻代的回收采用的是Minor GC(小规模垃圾回收),其特点是:

    • 对象创建频繁,但存活时间短。

    • GC周期较短,回收速度较快。

    • 采用标记-复制算法或标记-清除算法。

  2. 老年代(Old Generation)
    当年轻代中的对象经过多次垃圾回收后,依然存活,那么这些对象会被晋升到老年代。老年代用于存储生命周期较长的对象。由于老年代对象存活时间较长,所以垃圾回收的频率较低。老年代的回收采用的是Major GC(大规模垃圾回收),其特点是:

    • 对象存活时间较长,不易成为垃圾。

    • GC周期较长,回收速度较慢。

    • 采用标记-清除算法或标记-整理算法。

  3. 永久代/元空间(PermGen/Metaspace)
    在Java 8之前,类信息(如类的结构和方法的字节码)是存储在永久代中的。永久代的大小是固定的,无法动态调整。在Java 8中,永久代被元空间(Metaspace)取代,元空间位于本地内存中,且不再有固定大小的限制。因此,Java 8中的垃圾收集主要分为年轻代、老年代和元空间三个部分。对于元空间,垃圾回收的机制类似于老年代,采用标记-清除标记-整理算法。

2.3 为什么分代收集对性能至关重要?

分代收集的核心优势在于减少了垃圾回收的开销,特别是对年轻代的优化。具体来说,分代收集能够带来以下几个好处:

  1. 提高GC效率
    年轻代中的对象通常是短生命周期的,通过标记-复制算法(复制所有存活对象到新区域)来处理年轻代的垃圾回收,可以大幅提高回收效率。因为大多数新创建的对象会在较短时间内变为垃圾,及时回收这些短命对象,避免了不必要的复杂操作。

  2. 降低老年代的GC频率
    由于大多数对象在年轻代就会被回收,老年代对象的数量相对较少,垃圾回收的频率也会相应降低。这样一来,Major GC的发生频率减少,减轻了系统的负担。

  3. 提高内存利用率
    分代收集理论通过合理分配内存区域,可以避免内存碎片的产生,提高内存的使用效率。尤其是在年轻代的回收中,标记-复制算法能够有效减少内存碎片。

  4. 优化GC停顿时间
    由于年轻代的GC(Minor GC)回收时间短且频繁发生,可以确保老年代(Major GC)发生的时间较少,从而减少长时间的GC停顿。这对于需要低延迟的应用(如实时系统、Web服务器等)尤为重要。

2.4 分代收集的垃圾回收策略

在分代收集理论中,每一代的垃圾回收策略是不同的,主要体现在以下几个方面:

  1. 年轻代的回收(Minor GC)

    • 标记-复制算法:大部分年轻代的垃圾收集使用标记-复制算法,它将年轻代分为两部分,一个“From”区和一个“To”区。垃圾收集时,存活的对象会被复制到“To”区,清空“From”区。这样可以避免内存碎片,且回收速度较快。

    • 标记-清除算法:在某些情况下,年轻代可能会使用标记-清除算法。虽然这种算法会产生内存碎片,但它可以简化垃圾回收过程。

  2. 老年代的回收(Major GC)

    • 标记-清除算法:老年代的垃圾回收通常采用标记-清除算法,它会标记所有存活的对象,并清理没有被标记的对象。虽然该算法简单,但会产生内存碎片。

    • 标记-整理算法:为了避免内存碎片,老年代有时会使用标记-整理算法。这个算法除了标记存活对象外,还会将存活对象移动到一端,从而整理出一块连续的空闲区域。

  3. 元空间的回收

    • 对于Java 8引入的元空间,回收机制类似于老年代,主要依赖于标记-清除标记-整理算法。元空间的大小可以动态调整,因此在GC时,JVM会尝试清理不再使用的类信息,避免占用过多的本地内存。

3. 垃圾收集算法

在Java的垃圾收集机制中,主要有几种常见的垃圾收集算法,其中最基本的三种算法是:标记-清除算法、标记-复制算法和标记-整理算法。这些算法在不同的垃圾收集器中都有应用,且每种算法有不同的优缺点。接下来我们将逐一分析这几种算法的原理,并结合Java 8的实现进行讨论。

3.1 标记-清除算法
3.1.1 算法原理

标记-清除算法(Mark-and-Sweep)是最基本的垃圾收集算法之一。它的工作原理可以分为两个阶段:

  1. 标记阶段:从根对象(Root)开始,遍历整个对象图,标记所有仍然存活的对象。这些存活的对象一般是从栈上的活动对象或者静态变量等引用到的对象。

  2. 清除阶段:遍历堆中的所有对象,删除未被标记为存活的对象。被删除的对象占用的内存空间被释放。

3.1.2 优缺点
  • 优点

    • 实现简单:标记-清除算法的核心操作比较简单,易于理解和实现。

    • 适用于小型应用:对于一些对象较少且生命周期较短的应用,标记-清除算法能够较好地完成垃圾回收工作。

  • 缺点

    • 产生内存碎片:由于垃圾回收后的空闲内存并不是连续的,长时间运行后会产生内存碎片,导致堆内存的空间无法有效利用。

    • 回收效率较低:标记和清除两个阶段分别遍历整个堆,效率不高,尤其是对于存活对象较多时,回收过程较为缓慢。

3.1.3 Java 8中的实现

在Java 8中,标记-清除算法并没有被完全淘汰,而是依旧应用于一些垃圾收集器中,例如在Serial GCCMS GC的老年代回收过程中。尤其是在使用CMS GC时,当垃圾回收器无法保证回收足够多的内存时,会进入老年代的Full GC阶段,采用标记-清除算法进行清理。

配置示例

-XX:+UseCMSCompactAtFullCollection # 在Full GC时使用标记-清除算法
3.1.4 示例代码

在Java代码中,我们可以通过ManagementFactory来获取JVM的内存使用情况,辅助理解标记-清除过程中的内存变化。例如,以下代码可以帮助我们查看JVM内存的使用情况:

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;public class GCExample {public static void main(String[] args) {MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();System.out.println("Initial heap memory: " + heapMemoryUsage.getInit());System.out.println("Used heap memory: " + heapMemoryUsage.getUsed());System.out.println("Max heap memory: " + heapMemoryUsage.getMax());// 手动请求垃圾收集System.gc();heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();System.out.println("Used heap memory after GC: " + heapMemoryUsage.getUsed());}
}

该代码展示了如何获取和输出JVM堆内存的使用情况,并通过调用System.gc()模拟垃圾回收过程。

3.2 标记-复制算法
3.2.1 算法原理

标记-复制算法(Mark-and-Compact)是对标记-清除算法的一种改进。它通过将存活的对象复制到另一块内存区域来避免内存碎片问题。算法的过程通常包括以下两个阶段:

  1. 标记阶段:与标记-清除算法相同,首先标记所有存活的对象。

  2. 复制阶段:将所有标记为存活的对象复制到一个新的内存区域(通常称为“To区”)。之后,将原来的内存区域(“From区”)清空,从而避免了内存碎片。

标记-复制算法通常应用于年轻代的回收过程,特别是在Minor GC时。

3.2.2 优缺点
  • 优点

    • 避免内存碎片:由于对象被复制到一个连续的内存区域,不会出现内存碎片问题,内存利用率得到优化。

    • 回收效率高:标记-复制算法回收速度较快,适合年轻代频繁回收的场景。

  • 缺点

    • 内存浪费:标记-复制算法需要将存活对象复制到新的内存区域,这意味着至少需要两倍于当前堆大小的内存空间。对于内存较小的系统,可能会面临内存不足的问题。

    • 停顿时间较长:因为需要复制对象,导致回收过程中需要停顿较长时间。

3.2.3 Java 8中的实现

在Java 8中,标记-复制算法通常应用于年轻代的垃圾回收,特别是在Parallel GCSerial GC中。年轻代的GC会将存活的对象从“From区”复制到“To区”,清空“From区”以避免碎片。

配置示例

-XX:+UseSerialGC  # 使用标记-复制算法进行年轻代的垃圾回收
-XX:+UseParallelGC  # 使用并行标记-复制算法进行年轻代的垃圾回收
3.2.4 示例代码

使用System.gc()触发垃圾回收后,我们可以观察到年轻代垃圾收集的内存变化情况。以下代码展示了如何手动请求GC并查看内存使用情况:

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;public class MinorGCExample {public static void main(String[] args) {MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();System.out.println("Initial heap memory: " + heapMemoryUsage.getInit());System.out.println("Used heap memory: " + heapMemoryUsage.getUsed());// 手动请求垃圾回收System.gc();heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();System.out.println("Used heap memory after Minor GC: " + heapMemoryUsage.getUsed());}
}
3.3 标记-整理算法
3.3.1 算法原理

标记-整理算法(Mark-and-Compact)结合了标记-清除算法和复制算法的特点。它首先通过标记阶段标记所有存活的对象,然后通过整理阶段将存活对象压缩到堆的一端,清除剩余部分,从而避免了内存碎片的产生。

与标记-清除算法相比,标记-整理算法不需要复制对象,而是通过将存活对象压缩到堆的一端,整理出一块大的连续空闲空间。这对于长期运行的应用非常有效,因为它能够有效地回收内存而不产生碎片。

3.3.2 优缺点
  • 优点

    • 避免内存碎片:标记-整理算法通过压缩存活对象,确保堆内存的连续性,避免了内存碎片问题。

    • 高效回收:比标记-清除算法更加高效,不需要复制对象,因此减少了对象复制的开销。

  • 缺点

    • 回收过程较慢:由于需要整理内存,回收过程相对较慢,尤其是在堆较大的情况下。

    • 停顿时间较长:由于压缩存活对象,标记-整理算法的GC停顿时间较长。

3.3.3 Java 8中的实现

标记-整理算法主要用于老年代的垃圾回收,尤其是在CMS GCG1 GC中。老年代的回收会通过标记-整理算法压缩存活的对象,避免内存碎片的产生。

配置示例

-XX:+UseG1GC # 使用G1 GC时会采用标记-整理算法进行老年代回收
3.3.4 示例代码

可以使用System.gc()请求回收并通过代码查看内存变化。在使用G1 GC时,Java会自动选择合适的垃圾回收策略。

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;public class MajorGCExample {public static void main(String[] args) {MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();System.out.println("Initial heap memory: " + heapMemoryUsage.getInit());System.out.println("Used heap memory: " + heapMemoryUsage.getUsed());// 手动请求垃圾回收System.gc();heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();System.out.println("Used heap memory after Major GC: " + heapMemoryUsage.getUsed());}
}

4. Java 8中具体垃圾收集器的实现与应用

在Java 8中,JVM提供了多个垃圾收集器(GC),每个垃圾收集器都有其独特的算法实现,适用于不同的应用场景。常见的垃圾收集器包括Serial GCParallel GCCMS GCG1 GC。以下是每个垃圾收集器的简要介绍:

4.1 Serial GC

Serial GC是JVM的默认垃圾收集器,它采用了单线程方式进行垃圾回收。Serial GC适用于单核处理器或者对垃圾回收延迟要求不高的场景。它的特点是:

  • 适合小型应用或内存较小的环境。

  • 在进行垃圾回收时,会暂停所有应用线程,因此可能会造成较长时间的停顿。

  • 通过标记-复制算法对年轻代进行回收,通过标记-清除算法对老年代进行回收。

配置示例

-XX:+UseSerialGC
4.2 Parallel GC

Parallel GC(也称为吞吐量优先垃圾收集器)是多线程版本的Serial GC,它使用多个线程并行进行垃圾回收,能够提高回收的吞吐量。适用于多核机器和对应用吞吐量要求较高的场景。它的特点是:

  • 提高并发回收的效率,减少GC的停顿时间。

  • 在并行回收时,GC会尽量减少停顿时间,但相较于G1 GC,仍然可能出现较长的停顿。

  • 主要使用标记-复制算法对年轻代进行回收,标记-清除算法对老年代进行回收。

配置示例

-XX:+UseParallelGC
4.3 CMS GC(Concurrent Mark-Sweep)

CMS GC是一个低延迟垃圾收集器,旨在尽量减少应用的停顿时间。它通过并发的方式对堆中的对象进行标记、清除,并在清理垃圾时尽量不暂停应用程序线程。它的特点是:

  • 在进行GC时,尽量避免停顿,使得应用程序能够继续执行。

  • 适用于对响应时间要求较高的应用,如Web服务器等。

  • 使用标记-清除算法和标记-整理算法对年轻代和老年代进行回收。

配置示例

-XX:+UseConcMarkSweepGC
4.4 G1 GC(Garbage First)

G1 GC是Java 8引入的垃圾收集器,旨在为多核处理器提供更高效的垃圾收集。G1 GC将堆划分为多个区域(Region),通过精细的垃圾回收策略控制停顿时间。它的特点是:

  • 在回收过程中,尽量保证停顿时间可控,适合大内存应用。

  • 采用分区垃圾回收机制,可以灵活地调整不同区域的回收策略。

  • 对年轻代、老年代和元空间都采用标记-整理算法进行回收。

配置示例

-XX:+UseG1GC

Java 8中常见的几种垃圾收集器:Serial GC、Parallel GC、CMS GC和G1 GC。每种垃圾收集器有不同的特点,适用于不同的应用场景。在实际应用中,选择合适的垃圾收集器能够有效提升系统性能,降低垃圾回收带来的停顿时间。详细的每个垃圾收集器的分析和调优技巧,可以在我的专栏中找到对应的详细文章。

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

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

相关文章

Vmware中安装的CentOS7如何扩展硬盘大小

起初创建虚拟机时,大小设置不合理,导致我在尝试开源项目时空间不足重新扩展硬盘,不仅需要在虚拟机设置中配置,还需要在系统内重新进行分区一、虚拟机设置打开虚拟机设置→硬盘→扩展,将大小设置为自己期望的大小&#…

Python+MongoDB高效开发组合

如大家所知,Python与MongoDB的结合是一种高效的开发组合,主要用于通过Python进行数据存储、查询及管理,利用MongoDB的文档型数据库特性实现灵活的数据处理。下面让 Python 连接上 MongoDB:安装 PyMongo:pip3 install p…

【论文阅读】Masked Autoencoders Are Effective Tokenizers for Diffusion Models

introduce什么样的 latent 空间更适合用于扩散模型?作者发现:相比传统的 VAE,结构良好、判别性强的 latent 空间才是 diffusion 成功的关键。研究动机:什么才是“好的 latent 表征”?背景:Diffusion Models…

每日一SQL 【游戏玩法分析 IV】

文章目录问题案例执行顺序使用分组解决问题 案例 执行顺序 SQL 语句的执行顺序(核心步骤) 同一层级的select查询内部, 别名在整个 SELECT 计算完成前不生效 使用分组解决 select distinct s.product_id, Product.product_name from Sales sleft join …

内部文件审计:企业文件服务器审计对网络安全提升有哪些帮助?

企业文件服务器审计工作不仅对提升企业网络信息安全起到重要作用,还能对企业内部网络文件信息是否合规进行判断。因此企业文件服务器审计一直被高度重视。 一、文件服务器为何成为攻击焦点? 企业文件服务器通常集中存储财务报表、人事档案、研发资料、客…

FusionOne HCI 23 超融合实施手册(超聚变超融合)

产品介绍 FusionOne HCI作为实现企业信息一体化的IT基础设施平台,以“软硬件垂直深度集成和调优”、“快速部署”、“统一管理”的理念,提供应用融合部署,提升核心业务运作效率,降低整体采购成本。 FusionOne HCI代表了IT产品的…

AI算姻缘测算小工具流量主微信小程序开源

功能特点 响应式设计:完美适配各种移动设备屏幕尺寸 精美UI界面: 柔和的粉红色渐变背景 圆角卡片设计 精心设计的字体和间距 爱心图标点缀 动态效果: 点击按钮时的动画反馈 测算结果的平滑过渡动画 爱心漂浮动画 进度条动态填充 AI测算功能&a…

Vue获取上传Excel文件内容并展示在表格中

一、安装依赖 npm install xlsx 二、引用依赖 import XLSX from xlsx 三、代码实现 1、注意&#xff1a;函数 analysis 中reader.readAsBinaryString(file)&#xff0c;file的数据格式如图所示 2、示例代码 <!-- 项目使用的前端框架为非流行框架&#xff0c;主要关注…

pipelineJob和pipeline的关系

pipelineJob与pipeline在Jenkins体系中构成配置层与执行层的协同关系,具体关联如下: 一、核心功能定位 概念作用实现层级pipelineJob定义Job的元数据(如SCM配置、日志策略)配置层pipeline描述实际构建流程(如阶段划分、并行任务)执行层scriptPath桥梁作用:将配置层定义…

第二十篇 Word文档自动化:Python批量生成、模板填充与内容修改,告别繁琐排版!

python实现word 自动化重复性文档制作&#xff0c;手动填充模板&#xff0c;效率低下还易错1.python-docx入门&#xff1a;Word文档的“瑞士军刀”&#xff01;1.1 安装与基础概念&#xff1a;文档、段落、运行、表格1.2 打开/创建Word文档&#xff1a;Python与Word的初次接触1…

【C# in .NET】7. 探秘结构体:值类型的典型代表

探秘结构体&#xff1a;值类型的典型代表 在 C# 的类型系统中&#xff0c;结构体&#xff08;Struct&#xff09;作为值类型的典型代表&#xff0c;一直扮演着既基础又微妙的角色。许多开发者在日常编码中虽频繁使用结构体&#xff08;如int、DateTime等&#xff09;&#xff0…

深入探讨Hadoop YARN Federation:架构设计与实践应用

Hadoop YARN Federation简介基本概念与设计初衷Hadoop YARN Federation作为Apache Hadoop 3.x版本的核心特性之一&#xff0c;其本质是通过多集群联合管理机制突破单点资源管理器的性能瓶颈。传统YARN架构中&#xff0c;单个ResourceManager&#xff08;RM&#xff09;需要管理…

STM32固件升级设计——SD卡升级固件

目录 概述 一、功能描述 1、BootLoader部分&#xff1a; 2、APP部分&#xff1a; 二、BootLoader程序制作 1、分区定义 2、 主函数 3、SD卡升级文件检测和更新 4、程序跳转 三、APP程序制作 四、工程配置&#xff08;默认KEIL5&#xff09; 五、运行测试 结束语…

基于Python的图像文字识别系统

主要语言&#xff1a;Python数据库&#xff1a;SQLiteUI界面&#xff1a;PYQT5文字识别模型&#xff1a;Tesseract OCR&#xff08;本地搭建&#xff09;主要功能&#xff1a;登录注册&#xff1a;登录注册功能。图片管理&#xff1a;单张/多张上传、图片列表、预览、删除、切换…

028_分布式部署架构

028_分布式部署架构 概述 本文档介绍如何设计和实现Claude应用的分布式部署架构&#xff0c;包括负载均衡、缓存策略、服务发现、容错机制等。 微服务架构设计 1. 服务拆分策略 from abc import ABC, abstractmethod from typing import Dict, Any, Optional import asyncio im…

duckdb和pyarrow读写arrow格式的方法

arrow格式被多种分析型数据引擎广泛采用&#xff0c;如datafusion、polars。duckdb有一个arrow插件&#xff0c;原来是core插件&#xff0c;1.3版后被废弃&#xff0c;改为社区级插件&#xff0c;名字改为nanoarrow, 别名还叫arrow。 安装 D install arrow from community; D…

机器人位姿变换的坐标系相对性:左乘法则与右乘法则解析​

文章目录1. 全局坐标系下机器人位姿更新的左乘法则​2. 局部坐标系下机器人位姿增量更新的右乘法则​3. 相对位姿的计算3.1. 基于世界坐标系&#xff08;全局变换&#xff09;3.2. 基于 t1t_1t1​ 时刻相机的局部坐标系&#xff08;局部变换&#xff09;3.3. 两者区别设机器人当…

代码随想录算法训练营65期第20天

代码随想录算法训练营65期第20天 本文中使用到一些代码随想录里面的图片或者链接&#xff0c;在这里致敬程序员Carl 二叉搜索树的最近公共祖先 相对于 二叉树的最近公共祖先 本题就简单一些了&#xff0c;因为 可以利用二叉搜索树的特性。 题目链接&#xff1a;代码随想录&…

LLaMA.cpp HTTP 服务参数: --pooling 嵌入模型 池化类型详解

LLaMA.cpp HTTP 服务参数: --pooling 嵌入模型 池化类型详解 --pooling {none,mean,cls,last,rank} 在 llama.cpp 的 embedding server 中&#xff0c;--pooling {none,mean,cls,last,rank} 参数用于指定 如何将输入文本的 token 级嵌入向量聚合为句向量。以下是各选项的详细解…

「日拱一码」027 深度学习库——PyTorch Geometric(PyG)

目录 数据处理与转换 数据表示 数据加载 数据转换 特征归一化 添加自环 随机扰动 组合转换 图神经网络层 图卷积层&#xff08;GCNConv&#xff09; 图注意力层&#xff08;GATConv&#xff09; 池化 全局池化&#xff08;Global Pooling&#xff09; 全局平均池…