Java 内存泄漏 详解
Java 内存泄漏是指程序中某些对象不再被使用,但由于某些原因无法被垃圾回收器(Garbage Collector, GC)回收,导致内存被持续占用,最终可能引发性能问题或 OutOfMemoryError
。
本文将从底层原理、源码层面详细解释 Java 内存泄漏的成因、检测与解决方法,并以通俗易懂的语言来解释,方便初学者能理解。
1. Java 内存模型与垃圾回收基础
为了理解内存泄漏,我们需要先了解 Java 的内存模型和垃圾回收机制。
1.1 Java 内存模型
Java 虚拟机(JVM)将内存分为以下几个区域:
- 堆(Heap):存储对象实例和数组,是垃圾回收的主要区域。
- 栈(Stack):每个线程有自己的栈,存储方法调用的局部变量、方法参数和引用类型(指向堆中的对象)。
- 方法区(Method Area):存储类的元数据、静态变量和常量池(在 JDK 8 后改为元空间,Metaspace)。
- 程序计数器(Program Counter):记录当前线程执行的字节码指令地址。
- 本地方法栈(Native Method Stack):支持本地方法(Native Method)调用。
内存泄漏主要发生在堆中,因为对象是在堆中分配的,而垃圾回收器负责回收堆中不再使用的对象。
1.2 垃圾回收机制
JVM 的垃圾回收器通过以下步骤回收不再使用的对象:
- 标记(Marking):从根对象(GC Roots,例如栈中的引用、静态变量、本地方法栈中的引用等)开始,遍历所有可达对象,标记为“存活”。
- 清除(Sweeping):将未标记的对象(不可达对象)从内存中移除。
- 整理(Compacting,可选):将存活对象移动到一起,减少内存碎片。
垃圾回收算法包括:
- 标记-清除(Mark-Sweep):标记存活对象,清除未标记对象,可能导致内存碎片。
- 复制算法(Copying):将内存分为两块,存活对象复制到另一块,清除原块,适合年轻代。
- 标记-整理(Mark-Compact):标记后将存活对象整理到内存一端,减少碎片。
- 分代收集(Generational Collection):将堆分为年轻代(Young Generation)和老年代(Old Generation),年轻代使用复制算法,老年代使用标记-清除或标记-整理。
1.3 内存泄漏的本质
内存泄漏发生在对象本应被回收但由于某些引用关系仍然可达,导致垃圾回收器无法回收这些对象。换句话说,内存泄漏的根源是不必要的引用使得对象无法被标记为不可达。
2. Java 内存泄漏的常见原因
以下是导致内存泄漏的典型场景,结合底层原理和代码示例逐一分析。
2.1 静态变量持有对象引用
原理:静态变量的生命周期与类加载器绑定,直到程序结束或类被卸载才会释放。如果静态变量持有一个大对象的引用,这个对象将无法被回收。
代码示例:
import java.util.ArrayList;
import java.util.List;public class StaticLeak {// 静态变量private static List<Object> list = new ArrayList<>();public void addToList(Object obj) {list.add(obj); // 对象被静态变量引用}public static void main(String[] args) {StaticLeak leak = new StaticLeak();for (int i = 0; i < 1000000; i++) {leak.addToList(new byte[1024]); // 每次添加 1KB 的字节数组}// 即使循环结束,list 仍然持有所有对象的引用}
}
分析:
list
是静态变量,存储在方法区的静态区域。- 每次调用
addToList
,新创建的byte[]
数组被添加到list
,list
持有这些数组的引用。 - 垃圾回收器扫描时发现
list
是 GC Root,list
中的所有byte[]
都是可达的,无法回收。 - 随着循环次数增加,内存占用持续增长。
修复:
- 避免在静态变量中存储大量对象。
- 在适当时候清空静态集合(如
list.clear()
)或将静态变量置为null
。
2.2 未关闭的资源
原理:文件、网络连接、数据库连接等资源通常由操作系统管理,Java 对象(如 FileInputStream
)持有这些资源的句柄。如果未关闭资源,句柄不会释放,对象也无法被回收。
代码示例:
import java.io.FileInputStream;
import java.io.IOException;public class ResourceLeak {public void readFile(String path) {try {FileInputStream fis = new FileInputStream(path);// 读取文件byte[] buffer = new byte[1024];fis.read(buffer);// 忘记关闭 fis} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) {ResourceLeak leak = new ResourceLeak();for (int i = 0; i < 10000; i++) {leak.readFile("test.txt");}}
}
分析:
- 每次调用
readFile
,创建一个新的FileInputStream
对象,持有文件句柄。 - 如果不调用
fis.close()
,文件句柄不会释放,FileInputStream
对象仍然可达(可能被操作系统或其他引用链持有)。 - 循环多次调用后,创建大量
FileInputStream
对象,导致内存泄漏,甚至可能耗尽文件句柄。
修复:
- 使用
try-with-resources
确保资源自动关闭:
public void readFile(String path) {try (FileInputStream fis = new FileInputStream(path)) {byte[] buffer = new byte[1024];fis.read(buffer);} catch (IOException e) {e.printStackTrace();}
}
try-with-resources
利用AutoCloseable
接口,在try
块结束时自动调用close()
。
2.3 未移除的监听器
原理:在观察者模式中,监听器对象被添加到被观察者(如事件源)的集合中。如果监听器未被移除,它会一直被被观察者引用,无法回收。
代码示例:
import java.awt.*;
import java.awt.event.*;public class ListenerLeak extends Frame {public ListenerLeak() {Button button = new Button("Click Me");add(button);// 添加匿名监听器button.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("Button clicked!");}});setSize(200, 200);setVisible(true);}public static void main(String[] args) {ListenerLeak frame = new ListenerLeak();// 假设 frame 被销毁,但监听器未移除}
}
分析:
Button
内部维护一个ActionListener
列表,匿名监听器被添加到其中。- 如果
Frame
被销毁(例如关闭窗口),但未调用button.removeActionListener()
,监听器仍然被Button
引用。 Button
可能被其他对象(如 AWT 事件队列)引用,导致监听器无法回收。
修复:
- 在销毁对象时移除监听器:
button.removeActionListener(listener);
- 使用弱引用(
WeakReference
)存储监听器,允许垃圾回收器回收。
2.4 缓存未清理
原理:缓存(如 HashMap
或第三方缓存库)用于存储数据。如果缓存没有失效机制或未清理,缓存中的对象会一直占用内存。
代码示例:
import java.util.HashMap;
import java.util.Map;public class CacheLeak {private Map<String, byte[]> cache = new HashMap<>();public void addToCache(String key) {cache.put(key, new byte[1024 * 1024]); // 每次存 1MB 数据}public static void main(String[] args) {CacheLeak leak = new CacheLeak();for (int i = 0; i < 1000; i++) {leak.addToCache("key" + i);}// 缓存未清理,占用大量内存}
}
分析:
cache
存储大量byte[]
对象,每个对象占用 1MB。- 如果不移除缓存条目,
cache
中的所有对象都可达,无法回收。 - 随着键值对增加,内存占用持续增长。
修复:
- 使用具有失效机制的缓存,如
WeakHashMap
或第三方库(如 Guava Cache、Ehcache):
import java.util.WeakHashMap;public class CacheLeak {private Map<String, byte[]> cache = new WeakHashMap<>();// 其他代码同上
}
WeakHashMap
使用弱引用,当键不再被外部引用时,键值对可被回收。- 或者定期清理缓存:
cache.remove(key);
3. 内存泄漏的排查过程
当怀疑程序存在内存泄漏时,可以通过以下步骤排查:
3.1 观察症状
- 程序运行时间越长,内存占用越高。
- 频繁发生
OutOfMemoryError
。 - 垃圾回收频率增加,GC 时间变长。
3.2 使用监控工具
- JVisualVM:JDK 自带工具,监控堆使用情况、GC 行为。
- Eclipse MAT(Memory Analyzer Tool):分析堆转储(Heap Dump),查找泄漏对象。
- JProfiler:商业工具,提供详细的内存分析。
步骤:
- 获取堆转储:
- 使用
jmap
命令生成堆转储:jmap -dump:live,format=b,file=heap.bin <pid>
- 或在程序抛出
OutOfMemoryError
时自动生成(配置 JVM 参数-XX:+HeapDumpOnOutOfMemoryError
)。
- 使用
- 分析堆转储:
- 打开 Eclipse MAT,导入
heap.bin
。 - 使用“Dominator Tree”查看占用内存最多的对象。
- 检查“Paths to GC Roots”找到对象的引用链。
- 打开 Eclipse MAT,导入
- 定位代码:
- 根据引用链找到持有对象的代码(如静态变量、集合)。
- 检查代码逻辑,确认是否需要移除引用。
3.3 代码审查
- 检查静态变量、集合、资源关闭、监听器注册等。
- 使用静态分析工具(如 SonarQube)检测潜在问题。
4. 预防内存泄漏的最佳实践
-
谨慎使用静态变量:
- 避免在静态变量中存储大量数据。
- 使用后及时清理或置为
null
。
-
正确管理资源:
- 使用
try-with-resources
确保资源关闭。 - 释放数据库连接、网络连接等。
- 使用
-
使用弱引用或软引用:
对于缓存或监听器,使用WeakReference
或SoftReference
。 -
选择合适的缓存:
使用 Guava Cache 或 Caffeine,配置过期时间或最大容量。 -
定期监控内存:
在生产环境使用工具(如 Prometheus + Grafana)监控内存和 GC 行为。 -
编写单元测试:
测试资源是否正确关闭,集合是否被清理。
5. 从源代码层面分析 JVM 的垃圾回收
为了更深入理解内存泄漏,我们可以从 JVM 源代码(基于 OpenJDK)的角度分析垃圾回收的关键部分。
5.1 GC Roots 的定义
在 OpenJDK 中,GC Roots 由 oopClosure
和 OopStorage
等类处理,定义在 src/hotspot/share/gc/shared
目录下。GC Roots 包括:
- 栈中的局部变量和参数。
- 方法区中的静态变量。
- 本地方法栈中的 JNI 引用。
- 运行时常量池中的引用。
源码片段(gc/shared/gcCause.cpp
):
void GCCause::print_on(outputStream* st) const {switch (_cause) {case _java_lang_system_gc:st->print("System.gc()");break;case _full_gc_alot:st->print("FullGCAlot");break;// 其他原因}
}
- 垃圾回收从 GC Roots 开始,调用
markOop
方法标记可达对象。
5.2 标记阶段
标记阶段由 MarkSweep
或 G1CollectedHeap
等类实现。以 G1 垃圾回收器为例:
G1CollectedHeap::do_collection
调用G1ParScanThreadState
遍历对象图。- 使用
oopDesc
表示对象头,检查引用字段。
源码片段(gc/g1/g1CollectedHeap.cpp
):
void G1CollectedHeap::do_collection(bool explicit_gc, bool clear_all_soft_refs, size_t word_size) {// 标记存活对象G1ParScanThreadStateSet pss(this);G1CollectionSet coll_set(this);// 执行标记g1_policy()->record_collection_pause_start();
}
- 如果对象被 GC Root 引用,标记为存活,否则在清除阶段被回收。
5.3 内存泄漏的源代码视角
内存泄漏的核心是对象被 GC Root 引用。以静态变量为例:
- 静态变量存储在
InstanceKlass
的静态字段表中。 - 垃圾回收器在
SystemDictionary::do_unloading
中检查类是否可卸载,如果静态变量持有引用,类和对象都无法回收。
源码片段(systemDictionary.cpp
):
bool SystemDictionary::do_unloading(BoolObjectClosure* is_alive, OopClosure* keep_alive) {// 检查静态字段for (int i = 0; i < _num_buckets; i++) {for (DictionaryEntry* p = bucket(i); p != NULL; p = p->next()) {// 如果类被引用,无法卸载}}
}
- 如果开发者未清理静态变量,对象将一直存活。
6. 总结
Java 内存泄漏的本质是对象因不必要的引用而无法被垃圾回收器回收。常见原因包括静态变量、未关闭资源、监听器未移除和缓存未清理。通过理解 JVM 内存模型和垃圾回收机制,我们可以从以下方面预防和解决内存泄漏:
- 代码层面:正确管理引用、资源和缓存。
- 工具层面:使用 JVisualVM、Eclipse MAT 等工具排查。
- 源代码层面:理解 GC Roots 和标记清除过程,定位引用链。
通过遵循最佳实践和定期监控,可以有效减少内存泄漏的发生,确保程序高效运行。
相关文章:
Java 内存泄漏 详解
Java 内存泄漏是指程序中某些对象不再被使用,但由于某些原因无法被垃圾回收器(Garbage Collector, GC)回收,导致内存被持续占用,最终可能引发性能问题或 OutOfMemoryError。 本文将从底层原理、源码层面详细解释 Java …...
Rabbit MQ的基础认识
零、介绍 MQ:message queue(消息队列:先进先出) Rabbit MQ: 一、优势 1.应用解耦 2.异步提速 3.削峰填谷 4.总结 二、劣势...
GIS开发笔记(16)解决基于osg和osgearth三维地图上添加placeNode图标点击不易拾取的问题
一、实现效果 二、实现原理 在图标添加的位置同时添加一个红色圆球,半径为5000~8000米,图标和圆球挂接到同一个group节点,group节点再挂接到根节点,当点击到圆球时,通过遍历父节点就可以找到被点击的图标节点。 三、参考代码 //添加图标代码 #pragma once #include &…...
JDBC 使用流程详解
1. 加载数据库驱动 目的:注册数据库驱动类,使 JDBC 能识别特定数据库(如 MySQL、Oracle)。 代码示例: // JDBC 4.0 后无需显式加载驱动(SPI 自动发现),但部分旧项目仍需手动加载 C…...
小白学习java第16天(上): javaWeb
0.背景介绍 1.前言 首先我们需要javaweb里面的大概流程是干什么的,怎么才能实现的?,每一部分是靠什么进行的?以及背后实现的功能是干什么的?。。。。对于我来说要是不解决这些,会让我感觉不踏实ÿ…...
vue 打包设置
1、vue webpack配置 filename: [path][base].gz,// 设置成这样就行了 const { defineConfig } require(vue/cli-service)const debug process.env.NODE_ENV ! productionconst CompressionWebpackPlugin require(compression-webpack-plugin)const TerserPlugin require(…...
Excel如何安装使用EPM插件并且汉化?
Excel如何使用EPM插件 Excel如何使用EPM插件一、安装EPM插件二、启动EPM插件三、插件汉化设置 Excel如何使用EPM插件 一、安装EPM插件 在安装EPM插件时,若运行安装包后出现报错提示,通常是因为系统缺少 Visual Studio 2010 组件,需先安装该…...
在Linux中使用fcntl函数和ioctl函数
特性fcntlioctl作用对象文件描述符(通用文件操作)设备文件(硬件或驱动控制)标准化程度POSIX 标准,行为一致设备相关,无统一标准典型场景文件锁、非阻塞模式、描述符复制终端控制、网络配置、硬件操作移植性…...
ESP32-S3 入门学习笔记(四):LED实验
ESP32-S3 入门学习笔记(四):LED实验 开发板:正点原子ESP32S3 B站学习链接:link 1. GPIO&LED 简介 1.1 GPIO 简介 GPIO 是负责控制或采集外部器件信息的外设,主要负责输入输出功能。以下是ATK-MWS3S…...
clickhouse#复制修改数据
需求 在ClickHouse表中存在一些数据,你需要复制其中几行数据,这个复制不是完全复制,额外需要修改其中某几列数据项。 语句 INSERT INTO xxx_table SELECT * REPLACE ({except_value_1} AS {column_name_1},...{except_value_n} AS {colum…...
Java安全之cc链学习集合
CC1 InvokerTransformer https://blog.csdn.net/weixin_53912233/article/details/137786954 LazyMap https://blog.csdn.net/weixin_53912233/article/details/137787763 CC1链学习记录_cc1 链子 学习-CSDN博客 Java反序列化Commons-Collections篇02-CC1链补充 | Drunk…...
分享:google高级搜索常用的4个入口
网站和文件:google.com/advanced_search图片:google.com/advanced_image_search视频:google.com/advanced_video_search书籍:google.com/advanced_book_search...
内存四区(堆)
在上一次分享中,我和大家分享了栈区,今天栈区来了。 而内存四区中,堆区是干嘛的呢? 堆区,也是用来存放数据的,只不过呢,堆区中的数据的生死存亡是由程序员来控制的。 当然如果你一直不管堆区…...
Ldap高效数据同步- MirrorMode双主复制模式配置详解(下)
#作者:朱雷 上篇:《Ldap高效数据同步- MirrorMode双主复制模式配置详解(上)》 链接: link 文章目录 三、配置Mirror复制类型3.3. 在ldap-0上增加test2用户3.4. 在ldap-1上查看3.5. 在ldap-1上增加test4用户3.7. 最终两台LDAP数据…...
亚组风险比分析与可视化
1. 结果解读 1.1 风险比概述 1.1.1 风险比基本概念 风险比(Hazard Ratio)用于衡量治疗组与对照组事件发生的风险差异。 风险比为1,表示两组风险相同;小于1,治疗组风险低;大于1,治疗组风险高。 1.1.2 性别亚组分析 A性风险比小于1,表明治疗对A性有积极效果,风险降低。…...
2个小时1.5w字| React Golang 全栈微服务实战
文章目录 前言Golang 入门教程1. 下载与环境配置安装 GoWindows 安装macOS 安装Linux 安装 理解 GOROOT 和 GOPATHGOROOTGOPATHGo Modules 与 GOPATH 的关系查看和设置 Go 环境变量 配置 GOPATH 2. 语法与包管理Go 基础语法运行 Go 程序构建 Go 程序包管理 (Go Modules)常用标准…...
Spring security详细上手教学(三)密码管理
Spring security详细上手教学(三)密码管理 本章节两部分内容 实现PasswordEncoder使用Spring Security Crypto模块提供的工具 1. 使用 password encoder 通常,系统不会使用纯文本来保存密码,需要进行加密/哈希等一系列处理以加…...
ADC读取异常情况汇总
MCU ADC读取内部参考电压 Vrefint 如果某个输入引脚的电压高于供电电压,可能存在读取内部参考电压数值不准或者读数是4095。 虽然宽电压支持,最好硬件设计硬件避免这种情况,避免异常情况。...
给函数参数设置默认值的方式
在 JavaScript 中,给函数参数设置默认值主要有以下几种方式: 1. 函数体内手动检查赋值(ES5 及以前) 在函数内部检查参数是否为 undefined,然后手动赋值默认值。 function greet(name, age) {name name ! undefined…...
【C语言】内存分配的理解
很多时候我们声明变量,系统就自动为我们处理好了内存。 这主要取决于内存分配发生的时间和内存区域。C语言中主要有以下几种内存分配方式: 栈 (Stack) 内存分配 (自动内存): 何时发生: 在函数内部声明的非static局部变量(包括基本类型如 int…...
特征工程四:数据特征提取TfidfVectorizer的使用
TfidfVectorizer 深度解析 TfidfVectorizer 是 scikit-learn 中用于文本特征提取的核心工具,它将原始文本转换为 TF-IDF 特征矩阵,是自然语言处理(NLP)和文本挖掘的基础组件。 一、核心原理 1. TF-IDF 计算 TF (Term Frequency):词频&…...
深度学习涉及的数学与计算机知识总结
深度学习涉及的数学与计算机知识可总结为以下核心模块,结合理论与实践需求分为数学基础和计算机技能两大方向: 一、数学知识 线性代数 核心:矩阵运算(乘法、转置、逆矩阵)、向量空间、特征值与特征向量、奇异值分解&am…...
引领印尼 Web3 变革:Mandala Chain 如何助力 1 亿用户迈向数字未来?
当前 Web3 的发展正处于关键转折点,行业亟需吸引新用户以推动 Web3 的真正大规模采用。然而,大规模采用面临着核心挑战:数据泄露风险、集中存储的安全漏洞、跨系统互操作性障碍,以及低效的服务访问等问题。如何才能真正突破这些瓶…...
Mysql从入门到精通day6————时间和日期函数精讲
关于Mysql的日期和时间计算函数种类非常繁多,此处我们对常用的一些函数的用法通过实例演示让读者体会他们的用法,文章末尾也给出了时间和日期计算的全部函数 函数1:curdate()和current_date()函数 作用:获取当前日期 select curdate(),current_date();运行效果:...
C#如何正确的停止一个多线程Task?CancellationTokenSource 的用法。
在 C# 中停止一个 Task 需要谨慎处理,因为直接强制终止(如 Thread.Abort())会导致资源泄漏或状态不一致。推荐使用 协作式取消(Cooperative Cancellation) 通过 CancellationToken 实现安全停止。以下是详细方…...
【Redis】Redis Zset实现原理:跳表+哈希表的精妙设计
一、实现: Zset有序集合是一种由 跳表(Skip List)哈希表(Hash Table) 实现的数据结构。 二、特点功能: Set特性排序 三、跳表与哈希表分析: Zset的实现由两个数据结构: 1.跳表(Skip List):用于存储数据的排序和快…...
【前端】jQuery 对数据进行正序排列
你可以使用 jQuery 对数据进行正序排列(按 jbsj 升序)。以下是完整的代码示例: <!DOCTYPE html> <html> <head><title>按时间排序</title><script src"https://code.jquery.com/jquery-3.6.0.min.js&…...
Matlab 报错:尝试将 SCRIPT vl_sift 作为函数执行:
问题描述: 运行matlab程序出现报错: 警告: 名称不存在或不是目录: xxx\vlfeat-0.9.21\toolbox\mex\mexw64 xxxx 尝试将 SCRIPT vl_sift 作为函数执行: xxxx\vlfeat-0.9.21\toolbox\sift\vl_sift.m原因分析: 缺少 \vlfeat-0.9.21\toolbox…...
前端权限管理
前端权限 本质上就是控制前端视图层的展示和前端所发送的请求 一、RBAC 用户(User):系统的使用者 角色(Role):权限的集合(如管理员、普通用户)。 权限(Permission&am…...
【PVR】《Adaptive Palm Vein Recognition Method》
[1]程良彬.自适应的手掌静脉识别方法研究[D].桂林电子科技大学,2023.DOI:10.27049/d.cnki.ggldc.2023.000681. 文章目录 1、Background and Motivation2、Related Work3、Advantages / Contributions4、Method4.1、Datasets and Metrics4.2、基于最大化手掌内切圆的感兴趣区域提…...
MLLM之Bench:LEGO-Puzzles的简介、安装和使用方法、案例应用之详细攻略
MLLM之Bench:LEGO-Puzzles的简介、安装和使用方法、案例应用之详细攻略 目录 LEGO-Puzzles的简介 1、LEGO-Puzzles的特点 LEGO-Puzzles的安装和使用方法 1、安装 步骤 0:安装 VLMEvalKit 步骤 1:设置 API 密钥(可选…...
一周学会Pandas2 Python数据处理与分析-Pandas2数据信息查看操作
锋哥原创的Pandas2 Python数据处理与分析 视频教程: 2025版 Pandas2 Python数据处理与分析 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili DataFrame的基础信息和统计性信息。在我们拿到一 个数据集,用Pandas载入后,需要做一些初步的…...
【大模型微调与应用开发实战指南】从理论到工业级部署
目录 前言技术背景与价值当前技术痛点解决方案概述目标读者说明 一、技术原理剖析核心概念图解核心作用讲解关键技术模块说明技术选型对比 二、实战演示环境配置要求核心代码实现(LoRA微调)运行结果验证 三、性能对比测试方法论量化数据对比结果分析 四、…...
动手学深度学习11.10. Adam算法-笔记练习(PyTorch)
以下内容为结合李沐老师的课程和教材补充的学习笔记,以及对课后练习的一些思考,自留回顾,也供同学之人交流参考。 本节课程地址:72 优化算法【动手学深度学习v2】_哔哩哔哩_bilibili 本节教材地址:11.10. Adam算法 — 动手学深度学习 2.0.0 documentation 本节开源代码…...
Spring Boot API版本控制实践指南
精心整理了最新的面试资料和简历模板,有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 引言 在API迭代过程中,版本控制是保障系统兼容性的重要机制。合理的版本控制策略可以帮助开发团队平滑过渡接口变更,同时支持多版本客…...
如何让自己的博客可以在百度、谷歌、360上搜索到(让自己写的CSDN博客可以有更多的人看到)
发现自己写的博客文章名复制,然后粘贴到百度进行搜索,发现搜索不到自己的,但是会显示其他人的CSDN博客。于是查找相关资料,整理出以下搜索引擎资源收录入口,把自己的文章链接输入进去,然后经过审核通过后&a…...
Transformer
一、为什么需要Transformer?先看传统模型的痛点 1. 传统模型:RNN与CNN的短板 RNN(循环神经网络):逐个处理单词,像流水线作业。 问题:速度慢(无法并行&…...
LeetCode热题100--438.找到字符串中所有字母异位词--中等
1. 题目 给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。 示例 1: 输入: s “cbaebabacd”, p “abc” 输出: [0,6] 解释: 起始索引等于 0 的子串是 “cba”, 它是 “abc” 的异位词。 起始…...
仿微信上传头像,实现拍摄、相册选择、手动缩放、裁剪、蒙版、撤回、还原、上传微信本地文件功能
目前功能基于wx-cropper进行开发,wx-cropper 是一个基于微信小程序的图片裁剪工具 项目地址:gitcode地址 一、触发入口标签 <t-cell hover arrow class"userCell" catchtap"handleChangeHeadImg"><view slot"title&…...
Python 操作 Excel 插入图表:解锁数据可视化的高效密码
Python 操作 Excel 插入图表:解锁数据可视化的高效密码 在数据分析与展示的领域中,Python 凭借其强大的库支持,成为众多开发者与数据工作者的得力助手。将图表嵌入 Excel 文件,不仅能丰富数据呈现形式,还能让信息传递…...
python实战项目66:抓取考研招生专业信息
python实战项目66:抓取考研招生专业信息 一、流程分析二、完整代码一、流程分析 考研招生专业信息所在网页主页如下图: 在搜索框中输入所需查询的专业 点击“开设院校”,如下图所示: 打开浏览器开发者工具抓包,刷新页面,找到xhr数据包。 首先,在zydws.do数据包中抓…...
Awesome-Embodied-AI: 具身机器人的资源库
💡 你是否在寻找具身人工智能(Embodied AI)领域的研究资源?是否希望有一个系统性的资源集合来加速你的研究?今天给大家推荐一个重磅项目! 🌟 为什么需要这个项目? 具身人工智能是一…...
Java位运算符大全
1. Java 支持的位运算符 Java 提供了 7 种位运算符: 运算符名称描述示例&按位与(AND)两个位都为 1 时,结果才为 15 & 3 → 1|按位或(OR)两个位有一个为 1 时,结果就为 15 | 3 → 7^按…...
Using the NCCL Library: A Practical Guide
文章目录 Using the NCCL Library: A Practical GuidePrerequisitesBasic NCCL ConceptsPractical Demo CodeCompilation and ExecutionKey Steps ExplainedCommon Patterns1. Point-to-Point Communication2. Broadcast3. Using Streams Best Practices Using the NCCL Librar…...
UML 活动图详解之小轿车启动活动图分析
目录 一、UML 活动图概述 二、UML 活动图的构成元素详解 (一)活动 (二)动作状态 (三)活动状态 (四)迁移(转换) (五)初始节点 …...
58常用控件_QTextEdit的使用
目录 代码示例: 获取多行输入框的内容 代码示例:验证输入框的各种信号 QTextEdit 表示多行输入框也是一个富文本 & markdown 编辑器 并且能在内容超出编辑框范围时自动提供滚动条 QTextEdit不仅能表示纯文本,还可以表示html和markdown QPlainTextE…...
uniapp-商城-42-shop 后台管理 分包
在uniapp 的全局文件中,讲了分包 pages.json 页面路由 | uni-app官网 主要是用于小程序的打包。超高两M就不能上传的。 看看官网上是怎么说的。 1 subPackages 分包加载配置,此配置为小程序的分包加载机制。 因小程序有体积和资源加载限制…...
Zookeeper断开连接时分布式锁释放问题的解决方案
Zookeeper断开连接时分布式锁释放问题的解决方案 当Zookeeper客户端与服务器断开连接时,可能会导致分布式锁无法正常释放,这是分布式锁实现中需要重点解决的问题。以下是几种解决方案: 1. 利用Zookeeper临时节点的特性 核心原理࿱…...
Nginx配置文件介绍
Nginx 的配置文件是模块化的,不同的配置文件承担着不同的功能,下面为你详细介绍常见的配置文件及其作用: 这些文件在/etc/nginx/目录下: 1、主配置文件 /etc/nginx/nginx.conf 是 Nginx 的核心配置文件,对全局参数进…...
新闻数据接口开发指南:从多源聚合到NLP摘要生成
随着人工智能(AI)技术的飞速发展,新闻行业也迎来了新的变革。AI不仅能够自动化生成新闻内容,还能通过智能推荐系统为用户提供个性化的新闻体验。万维易源提供的“新闻查询”API接口,结合了最新的AI技术,为开…...