JVM 生产环境问题定位与解决实战(七):实战篇——OSSClient泄漏引发的FullGC风暴
本文已收录于《JVM生产环境问题定位与解决实战》专栏,完整系列见文末目录
引言
在前六篇博客中,我们系统性地学习了 JVM 生产环境问题定位与解决的全套工具链,涵盖jps
、jmap
、jstat
、jstack
、jcmd
等基础工具的使用技巧,深入剖析了JConsole
、VisualVM
和 MAT
的高级应用场景,探索了JFR
与JMC
的性能分析能力,并解锁了Arthas
的在线诊断黑科技。为使读者能将理论知识转化为实战能力,笔者将分享三个真实的线上疑难案例:
- OSSClient 未关闭导致的内存泄漏和 CPU 飙升(本篇详解)
- 正则表达式回溯导致的 CPU 100%
- JVM 内存区域分配不合理导致的频繁 Full GC
本文将重点解析首个案例,完整展现从现象捕捉、根因定位到方案优化的全链路故障排查过程。
案例一:OSSClient泄漏引发的FullGC风暴
问题现象
某日线上系统突现异常:
- 接口响应延迟:TP99从200ms飙升至5s+,部分请求超时失败
- 资源指标异常:阿里云ECS服务器CPU持续150%+,Load值突破15
- 堆内存告急:Old Gen占用率>99%且持续高位
- GC风暴:每分钟触发3-4次Full GC,单次耗时8-10秒,但回收效率近乎为零
排查过程
1. 系统资源监控(TOP命令分析)
通过top
命令快速锁定异常进程:
top - 14:32:01 up 45 days, 2:15, 3 users, load average: 15.23, 14.87, 13.65
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
13749 app 20 0 26.8g 5.2g 34832 S 207.3 34.6 45:32.19 java
关键发现:
- Java进程(PID=13749)CPU占用率突破200%
- 物理内存消耗达5.2GB,存在内存泄漏嫌疑
2. 线程级CPU分析(TOP -H 定位高 CPU 线程)
通过top -H -p <pid>
穿透进程查看线程级资源占用:
top -H -p 13749
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
17911 app 20 0 12.9g 8.2g 2.3g R 99.6 26.3 45:67.89 java
17912 app 20 0 12.9g 8.2g 2.3g R 97.2 26.3 44:32.10 java
关键发现:
-
多个线程(如17911、17912)CPU占用率接近100%
-
将十进制PID转为十六进制(
printf "%x\n" 17911
=> 45f7)用于线程堆栈分析#转换为十六进制:printf "%x\n" 17911 # 输出:45f7printf "%x\n" 17912 # 输出:45f8
3. 线程堆栈分析(jstack定位GC线程)
运行jstack <pid>
生成线程堆栈快照,在生成的thread_dump.txt中搜索对应的十六进制线程ID,获取线程快照并定位热点线程:
jstack 13749 > thread_dump.txt
在thread_dump.txt
中搜索nid=0x45f7
,发现高CPU线程为GC线程:
Locked ownable synchronizers:
- None"VM Thread" os_prio=0 tid=0x00002b71d00ff800 nid=0x45f9 runnable "GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00002b71d0023800 nid=0x45f7 runnable "GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00002b71d0025800 nid=0x45f8 runnable "VM Periodic Task Thread" os_prio=0 tid=0x00002b71d034f800 nid=0x4870 waiting on condition
结论:
GC线程持续运行,说明JVM在进行高频率垃圾回收,但老年代空间无法释放。
4. GC行为监控(jstat动态观测)
使用jstat -gcutil
监控GC动态:
jstat -gcutil 13749 5000
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 0.00 85.58 99.99 93.67 89.78 5525 805.725 1007 9100.289 9906.014
0.00 0.00 100.00 99.99 93.67 89.78 5525 805.725 1008 9100.289 9906.014
0.00 0.00 100.00 99.99 93.67 89.78 5525 805.725 1008 9100.289 9906.014
0.00 0.00 40.57 99.99 93.66 89.78 5525 805.725 1008 9109.816 9915.541
0.00 0.00 71.48 99.99 93.66 89.78 5525 805.725 1008 9109.816 9915.541
0.00 0.00 90.87 99.99 93.66 89.78 5525 805.725 1008 9109.816 9915.541
0.00 0.00 100.00 99.99 93.66 89.78 5525 805.725 1009 9109.816 9915.541
0.00 0.00 30.91 99.99 93.66 89.78 5525 805.725 1009 9118.757 9924.482
0.00 0.00 55.48 99.99 93.66 89.78 5525 805.725 1009 9118.757 9924.482
0.00 0.00 76.63 99.99 93.66 89.78 5525 805.725 1009 9118.757 9924.482
0.00 0.00 97.42 99.99 93.66 89.78 5525 805.725 1009 9118.757 9924.482
0.00 0.00 100.00 99.99 93.66 89.78 5525 805.725 1010 9118.757 9924.482
0.00 0.00 24.04 99.99 93.66 89.78 5525 805.725 1010 9127.980 9933.705
0.00 0.00 68.32 99.99 93.66 89.78 5525 805.725 1010 9127.980 9933.705
0.00 0.00 91.50 99.99 93.66 89.78 5525 805.725 1010 9127.980 9933.705
0.00 0.00 100.00 99.99 93.66 89.78 5525 805.725 1011 9127.980 9933.705
0.00 0.00 100.00 99.99 93.66 89.78 5525 805.725 1011 9127.980 9933.705
0.00 0.00 50.42 99.99 93.66 89.78 5525 805.725 1011 9137.226 9942.951
0.00 0.00 83.94 99.99 93.66 89.78 5525 805.725 1011 9137.226 9942.951
0.00 0.00 100.00 99.99 93.66 89.78 5525 805.725 1012 9137.226 9942.951
0.00 0.00 100.00 99.99 93.66 89.78 5525 805.725 1012 9137.226 9942.951
0.00 0.00 54.98 99.99 93.66 89.78 5525 805.725 1012 9146.092 9951.817
0.00 0.00 85.01 99.99 93.66 89.78 5525 805.725 1012 9146.092 9951.817
0.00 0.00 100.00 99.99 93.66 89.78 5525 805.725 1013 9146.092 9951.817
0.00 0.00 100.00 99.99 93.66 89.78 5525 805.725 1013 9146.092 9951.817
0.00 0.00 51.21 99.99 93.66 89.78 5525 805.725 1013 9155.524 9961.249
0.00 0.00 89.83 99.99 93.66 89.78 5525 805.725 1013 9155.524 9961.249
0.00 0.00 100.00 99.99 93.66 89.78 5525 805.725 1014 9155.524 9961.249
0.00 0.00 100.00 99.99 93.66 89.78 5525 805.725 1014 9155.524 9961.249
0.00 0.00 100.00 99.99 93.66 89.78 5525 805.725 1014 9155.524 9961.249
0.00 0.00 100.00 99.99 93.66 89.78 5525 805.725 1014 9155.524 9961.249
0.00 0.00 88.08 99.99 93.71 89.72 5525 805.725 1014 9174.692 9980.417
0.00 0.00 100.00 99.99 93.71 89.72 5525 805.725 1015 9174.692 9980.417
0.00 0.00 100.00 99.99 93.71 89.72 5525 805.725 1015 9174.692 9980.417
0.00 0.00 57.17 99.99 93.71 89.72 5525 805.725 1015 9187.097 9992.822
0.00 0.00 100.00 99.99 93.71 89.72 5525 805.725 1016 9187.097 9992.822...(持续增长)
关键指标解读:
- O(老年代Old Gen):持续99.99%,Full GC无法回收
- YGC(年轻代GC事件发生的次数) : 共 5525 次,但最近未增加。
- YGCT(年轻代GC所花费的总时间):805.725 秒,平均每次 Minor GC 耗时约 0.146 秒。
- FGC(Full GC事件发生的次数):Full GC频率异常,持续增加,这表明 Old 区已满,垃圾回收器无法有效回收内存。
- FGCT(Full GC所花费的总时间):Full GC总耗时突破9187秒,平均每次 Full GC 耗时约 9.04 秒。
由于 Full GC 会触发 “Stop-the-World” 机制,导致应用程序暂停,对系统性能造成显著影响。结合线程堆栈分析和 GC 行为特征,可以判定请求响应延迟的根源在于频繁的 Full GC。接下来需要深入分析引发 GC 异常的具体原因,例如内存泄漏、对象生命周期管理不当或大对象分配失控等。
5. 堆内存转储(jmap生成hprof文件)
使用jmap -dump:live,format=b,file=heap.hprof <pid>
生成堆转储文件,以便分析内存占用情况。
jmap -dump:live,format=b,file=heap.hprof 13749
将heap.hprof下载到本地,利用工具进行分析。
6. 内存泄漏分析(MAT深度解析)
使用Eclipse Memory Analyzer(MAT)分析heap.hprof:
Step 1 - Leak Suspects报告
堆转储文件可能包含大量对象,MAT 的 Leak Suspects 报告能快速识别潜在的内存泄漏点,因此首先运行此报告。
报告发现大量 org.apache.http.impl.conn.PoolingHttpClientConnectionManager
实例由 com.aliyun.oss.common.comm.IdleConnectionReaper @ 0x6ce2d8388
线程加载,占用 Old
区内存。这提示我们 Full GC
可能与这些对象有关。
Step 2 - Histogram视图
Leak Suspects
报告指出了 PoolingHttpClientConnectionManager
的内存占用问题,但需要量化具体类及其内存占用比例,因此查看 Histogram
直方图。在MAT的Overview
页面,打开Histogram
直方图,按Retained Heap
(保留堆大小)倒序排序,发现以下类占用大量内存:
org.apache.http.impl.conn.PoolingHttpClientConnectionManager
com.aliyun.oss.common.comm.DefaultServiceClient
其中,DefaultServiceClient
是阿里云OSS SDK中的类,提示问题可能与OSS相关。
Step 3 - 按包分组分析
Histogram
直方图确认了具体类的内存占用,但是存在大量的基础类型(如char[]
、String
)和集合的实例,这些通常不是内存泄漏根源,因此按包分组分析,更容易发现项目自定义类。在 Histogram
视图中,选择 Group by package
,查看哪些包的类占用内存较多。结果显示,com.aliyun.oss
包下的类内存占用显著,确认问题与阿里云OSS组件相关。
Step 4 - 引用链追踪
按包分组基本确认了阿里云 OSS
相关类的内存占用,但需要明确这些对象为何未被 GC
回收,因此分析其引用关系以找到 GC Root
。查看 org.apache.http.impl.conn.PoolingHttpClientConnectionManager
的引用关系,进行 Path To GC Roots -> exclude all phantom/weak/soft etc. references
操作,得到所有强引用的引用路径。
发现 com.aliyun.oss.common.comm.IdleConnectionReaper @ 0x6ce2d8388
线程持有对这些对象的引用,与 Leak Suspects
报告一致。
Step 5- 查看线程细节
GC Root
指向 IdleConnectionReaper
线程,非项目自定义类。需要了解该线程的角色和行为以判断其为何持有这些对象,因此查看线程细节。进一步查看IdleConnectionReaper
线程的Thread Detail
。
查看 IdleConnectionReaper
的 Thread Detail
,确认这是一个守护线程,负责管理连接池。
由于 IdleConnectionReaper
是一个守护线程(is Daemon = true
),它作为 JVM 的一个独立线程运行,且通常不会随着用户线程的结束而终止。守护线程本身可以作为 GC Root
,因为 JVM 必须保持其存活以执行后台任务(如连接池清理)。这意味着由 IdleConnectionReaper
持有的对象(如 PoolingHttpClientConnectionManager
)可能无法通过常规的引用链分析直接查到其创建来源,因为这些对象的 GC Root
是守护线程的静态变量 connectionManagers
,而不是业务代码中的直接引用。这增加了定位问题代码的难度,可能需要结合其他工具(如 Arthas
)来追踪对象的创建路径.
Step 6 - 分析源码
Thread Detail
指向了 IdleConnectionReaper.java:78
,确认了是守护线程,但需要通过源码了解其如何持有 PoolingHttpClientConnectionManager
以及为何未释放,因此分析相关源码。
查看 IdleConnectionReaper.java:78
源码,发现该线程每隔 5 秒检查一次连接池,关闭过期和空闲时间超过 60 秒的连接。PoolingHttpClientConnectionManager
实例被添加到静态变量 ArrayList<HttpClientConnectionManager> connectionManagers 中
,通过 registerConnectionManager()
方法添加,通过 removeConnectionManager()
或 shutdown()
方法释放.
分析得出:程序通过 IdleConnectionReaper
的 registerConnectionManager()
方法创建了大量 PoolingHttpClientConnectionManager
对象,但未通过 removeConnectionManager()
或 shutdown()
方法释放,导致这些对象无法被 GC 回收。
Step 7- 分析引用关系
源码分析确认 IdleConnectionReaper
因未调用释放方法导致内存泄漏,但仍未定位系统中 PoolingHttpClientConnectionManager
的创建来源,因此需要查看其引用关系以追踪创建点。
在 Histogram
视图中,右键选择 incoming/outgoing references
查看 PoolingHttpClientConnectionManager
的引用关系,发现 com.aliyun.oss.common.comm.DefaultServiceClient
也与这些对象相关.
Step 8- 进一步分析 DefaultServiceClient
引用关系显示 DefaultServiceClient
与 PoolingHttpClientConnectionManager
相关,但需要通过源码确认其如何创建和管理这些对象,因此分析 DefaultServiceClient
源码。
查看 DefaultServiceClient
源码,发现其在构造时调用 IdleConnectionReaper.registerConnectionManager()
,在 shutdown()
方法中调用 IdleConnectionReaper.removeConnectionManager()
.
得出结论:项目中创建了大量 DefaultServiceClient
实例,但未调用 shutdown()
方法释放资源.
Step 9-代码溯源(Arthas热诊断)
问题定位的难点:DefaultServiceClient
分析确认了未调用 shutdown()
的问题,但仍需确定具体业务代码为何创建大量实例,尤其是在系统长期稳定后突然触发问题,因此需要进一步追踪。
至此,已基本确定问题是 OSSClient
未关闭导致的资源泄漏,但需要进一步定位具体业务代码。MAT 分析显示 PoolingHttpClientConnectionManager
和 DefaultServiceClient
的 GC root
均为 IdleConnectionReaper
的静态变量 connectionManagers
,且导出堆转储时执行了 GC, OSSClient
实例已被回收,难以直接追溯到具体代码。
MAT 分析受限于 GC Root 和堆转储时的 GC 影响,无法直接定位业务代码。那么有什么方法能定位到 PoolingHttpClientConnectionManager
是如何创建的吗?
在第五篇文章《JVM生产环境问题定位与解决实战(五):Arthas——不可错过的故障诊断利器》中介绍了stack - 输出当前方法被调用的调用路径
,很符合我们的需求。
使用 Arthas 的 stack
命令输出 PoolingHttpClientConnectionManager
构造方法的调用路径:
stack org.apache.http.impl.conn.PoolingHttpClientConnectionManage
最终定位:新增的批量处理业务逻辑在 com.controller.TestController.createOSSClient(TestController.java:423)
中创建了大量OSSClient实例,使用后未关闭,导致内存泄漏。
问题原因
综合排查结果,问题根源如下:
- 业务代码中批处理业务使用OSSClient访问阿里云OSS时,未调用shutdown()方法释放资源。
- 每个OSSClient实例关联一个PoolingHttpClientConnectionManager对象,这些对象被IdleConnectionReaper的静态变量connectionManagers持有,无法被垃圾回收。
- 大量未释放的PoolingHttpClientConnectionManager实例占满老年代,触发频繁的Full GC。
- Full GC为“Stop-the-World”事件,导致应用线程暂停,GC线程占用大量CPU,表现为CPU使用率飙升至200%及请求延迟。
优化建议
-
正确释放资源:确保在使用
OSSClient
后调用shutdown()
。推荐使用try-finally
或try-with-resources(若SDK支持AutoCloseable)
:OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); try {ossClient.putObject(bucketName, key, new File("file.txt")); } finally {ossClient.shutdown(); }
-
单例模式优化:如果
OSSClient
需要重复使用,可通过单例模式或连接池管理,避免频繁创建和销毁:public class OSSClientHolder {private static final OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);public static OSS getOSSClient() {return ossClient;}public static void shutdown() {ossClient.shutdown();} }
验证
为验证优化措施的效果,进行了以下实验:
- createOSSClient:存在问题的原始代码,未关闭 OSSClient 实例。
- createOSSClient1:优化后的代码,使用后调用 shutdown() 释放 OSSClient 实例。
- createOSSClient2:优化后的代码,采用单例模式管理单一 OSSClient 实例。
实验环境与流程
- 环境设置:
- 项目启动时启用 JVM GC 日志,配置参数为:
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseSerialGC
。 - 使用
jvisualvm
工具连接到 Java 进程进行监控。 - 使用
JMeter
进行1000次并发请求。
- 项目启动时启用 JVM GC 日志,配置参数为:
- 测试流程:
-
对三种方法(
createOSSClient
、createOSSClient1
、createOSSClient2
)分别进行 1000 次压力测试。 -
在 jvisualvm 的抽样器(Sampler)界面,设置内存监控,并使用正则表达式筛选以下对象:
(org\.apache\.http\.impl\.conn\.PoolingHttpClientConnectionManager|com\.aliyun\.oss\.OSSClient|com\.aliyun\.oss\.common\.comm\.DefaultServiceClient)
-
分析 GC 日志和 jvisualvm 快照,观察实例数量和 GC 行为。
-
测试结果
createOSSClient(问题代码)
-
行为:创建 1000 个 PoolingHttpClientConnectionManager、OSSClient 和 DefaultServiceClient 实例。
-
GC 结果:
- OSSClient 实例最终能够被垃圾回收。
- 由于 IdleConnectionReaper 的静态引用,PoolingHttpClientConnectionManager 和 DefaultServiceClient 实例无法被回收,,导致内存泄漏。
-
可视化证据:
createOSSClient1(资源清理)
- 行为:创建 1000 个实例,但在使用后调用 shutdown() 释放 OSSClient 资源。
- GC 结果:
- 经过两次 Minor GC,所有 1000 个 PoolingHttpClientConnectionManager、OSSClient 和 DefaultServiceClient 实例被完全回收。
- 第一次 GC:
- OSSClient 实例全部回收。
- PoolingHttpClientConnectionManager 和 DefaultServiceClient 部分回收。
- GC 日志:
2025-04-22T17:20:53.987-0800: 776.023: [GC (Allocation Failure) 2025-04-22T17:20:53.987-0800: 776.023: [DefNew: 148740K->17299K(157248K), 0.0224669 secs] 188299K->59312K(506816K), 0.0225411 secs] [Times: user=0.02 sys=0.00, real=0.02 secs]
- 可视化证据:
- 第二次 GC:
- 剩余的 PoolingHttpClientConnectionManager 和 DefaultServiceClient 实例全部回收。
- GC 日志:
2025-04-22T17:24:47.531-0800: 1009.572: [GC (Allocation Failure) 2025-04-22T17:24:47.531-0800: 1009.572: [DefNew: 157075K->5760K(157248K), 0.0193343 secs] 199088K->60437K(506816K), 0.0193803 secs] [Times: user=0.01 sys=0.01, real=0.02 secs]
createOSSClient2(单例模式)
-
行为:仅创建 1 个 PoolingHttpClientConnectionManager、OSSClient 和 DefaultServiceClient 实例。
-
GC 结果:
- OSSClient 实例在 Minor GC 后被回收。
- 手动触发 Full GC 后,PoolingHttpClientConnectionManager 和 DefaultServiceClient 仍保留 1 个实例(符合单例模式预期)。
2025-04-22T18:04:12.163-0800: 141.076: [GC (Allocation Failure) 2025-04-22T18:04:12.163-0800: 141.076: [DefNew: 147843K->17471K(157248K), 0.0190248 secs] 186553K->62863K(506816K), 0.0190696 secs] [Times: user=0.01 sys=0.00, real=0.02 secs] 2025-04-22T18:04:24.007-0800: 152.920: [Full GC(手动触发) (System.gc()) 2025-04-22T18:04:24.007-0800: 152.920: [Tenured: 45391K->59618K(349568K), 0.0779813 secs] 74436K->59618K(506816K), [Metaspace: 48021K->48021K(1093632K)], 0.0782380 secs] [Times: user=0.07 sys=0.00, real=0.08 secs]
-
可视化证据:
结论
实验结果验证了问题分析和优化建议的正确性:
- 不调用shutdown()会导致内存泄漏:PoolingHttpClientConnectionManager等关键组件无法回收
- 正确调用shutdown()可解决问题:所有资源都能被GC正常回收
- 单例模式是更优方案:既能避免资源泄漏,又能减少重复创建开销
建议在实际项目中:
- 对于短期使用的OSSClient,必须使用try-finally保证关闭
- 对于频繁使用的场景,推荐使用单例模式管理
- 定期监控JVM内存和GC情况,及早发现潜在问题
附录:系列目录
- JVM生产环境问题定位与解决实战(一):掌握jps、jmap、jstat、jstack、jcmd等基础工具
- JVM生产环境问题定位与解决实战(二):JConsole、VisualVM到MAT的高级应用
- JVM生产环境问题定位与解决实战(三):揭秘Java飞行记录器(JFR)的强大功能
- JVM生产环境问题定位与解决实战(四):使用JMC进行JFR性能分析指南
- JVM生产环境问题定位与解决实战(五):Arthas——不可错过的故障诊断利器
- JVM生产环境问题定位与解决实战(六):总结篇——问题定位思路与工具选择策略
- ➡️ 当前:JVM 生产环境问题定位与解决实战(七):实战篇——OSSClient泄漏引发的FullGC风暴
🔥 下篇预告:《JVM 生产环境问题定位与解决实战(八):实战篇——正则表达式回溯导致的 CPU 100%》
🚀 关注作者,获取实时更新通知!有问题欢迎在评论区交流讨论~
相关文章:
JVM 生产环境问题定位与解决实战(七):实战篇——OSSClient泄漏引发的FullGC风暴
本文已收录于《JVM生产环境问题定位与解决实战》专栏,完整系列见文末目录 引言 在前六篇博客中,我们系统性地学习了 JVM 生产环境问题定位与解决的全套工具链,涵盖jps、jmap、jstat、jstack、jcmd 等基础工具的使用技巧,深入剖析…...
缩放点积注意力
Scaled Dot-Product Attention 论文地址 https://arxiv.org/pdf/1706.03762 注意力机制介绍 缩放点积注意力是Transformer模型的核心组件,用于计算序列中不同位置之间的关联程度。其核心思想是通过查询向量(query)和键向量(key&am…...
一个关于相对速度的假想的故事-7
回到, 它其实还可以写成, 也就是说,把 作为1,它的 倍也是存在和成立的。或者说,如果认为 是某一种单位(虚数 为单位),那么 的平方 显然也是一种单位(-1为单位)…...
LeetCode算法题(Go语言实现)_57
题目 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 一、代码实现(回溯法) func letterCombinatio…...
从GPT-5到Claude 3:大模型竞赛的下一站是什么?
从GPT-5到Claude 3:大模型竞赛的下一站是什么? 引言 随着人工智能技术的飞速发展,大语言模型(LLM)已经成为推动自然语言处理(NLP)领域进步的关键力量。自2018年OpenAI推出GPT-1以来࿰…...
leetcode - 字符串
字符串 466. 统计重复个数 题目 定义 str [s, n] 表示 str 由 n 个字符串 s 连接构成。 例如,str ["abc", 3] "abcabcabc" 。 如果可以从 s2( )中删除某些字符使其变为 s1,则称字符串 s1( )可以从字符串 s2 获得。 例如…...
运维打铁:网络基础知识
文章目录 一、网络架构1. 网络架构图2. 各层级功能3. 机房网络常见问题及解决方案 二、交换技术1. 交换技术基础2. 交换技术分类3. 广播域相关概念4. ARP 协议5. 三层交换机6. VLAN(虚拟局域网) 三、路由技术1. 路由器端口类型及功能2. 路由器功能3. 路由…...
黑马商城-微服务笔记
认识微服务 单体架构 微服务架构 微服务拆分 服务拆分原则 什么时候拆分? ●创业型项目:先采用单体架构,快速开发,快速试错。随着规模扩大,逐 渐拆分。 ●确定的大型项目:资金充足,目标明确&a…...
XCZU19EG-2FFVC1760I Xilinx赛灵思FPGA Zynq UltraScale+MPSoC
XCZU19EG-2FFVC1760I 属于 Zynq UltraScaleMPSoC EG(Enhanced General)系列,采用 20nm FinFET 工艺制造,该型号的速度等级为 -2(0.85V VCCINT)、工业级温度(-40℃ 至 100℃)…...
第六章 QT基础:3、QT的打包和部署
问题一:什么是打包和部署? 打包和部署是将开发完成的程序分发给用户并使其能够在目标环境中运行的两个重要步骤。 打包:指的是将开发完成的程序及其依赖的所有资源(如图标、配置文件、动态链接库、字体等)打包成一个可…...
【测试报告】幸运闪烁抽奖系统(Java+Selenium+Jmeter自动化测试)
一、项目背景 幸运闪烁抽奖系统 是一款基于 Spring Boot 实现的前后端分离式的网络抽奖系统,操作便捷,安全可靠。有管理员和普通用户两个角色,支持管理员创建普通用户、新建活动奖品、创建抽奖活动、进行抽奖、通过短信/邮箱通知中奖用户等功…...
块压缩与图片压缩优缺点对比
块压缩与图片压缩优缺点对比 块压缩(Block Compression) ✅ 优点 硬件加速支持 直接被GPU读取,无需CPU解压显著降低内存带宽消耗(适合移动设备) 随机访问特性 44/88像素块独立压缩支持直接定位读取特定纹理区域 固…...
C++算法(14):K路归并的最优解法
问题描述 给定K个按升序排列的数组,要求将它们合并为一个大的有序数组。例如,输入数组[[1,3,5], [2,4,6], [0,7]],合并后的结果应为[0,1,2,3,4,5,6,7]。 解决方案 思路分析 合并多个有序数组的高效方法是利用最小堆(优先队列&…...
2025.04.23【Treemap】树状图数据可视化指南
Multi-level treemap How to build a treemap with group and subgroups. Customization Customize treemap labels, borders, color palette and more 文章目录 Multi-level treemapCustomization Treemap 数据可视化指南Treemap 的基本概念为什么使用 TreemapTreemap 的应用…...
2025新一代人工智能技术发展及其应用
新一代人工智能技术发展及其应用 一、人工智能概述(一)定义(二)动力(三)发展脉络 二、新一代人工智能技术(一)大语言模型(二)自然语言处理(三&…...
vue3中slot(插槽)的详细使用
在 Vue 3 中,slot(插槽)是一种强大的组件内容分发机制,它允许父组件向子组件传递内容,从而使组件的使用更加灵活。以下是关于 Vue 3 中 slot 的详细介绍 一、默认插槽 这是最基本的插槽形式。子组件中使用定义一个插…...
大模型面经 | 春招、秋招算法面试常考八股文附答案(五)
大家好,我是皮先生!! 今天给大家分享一些关于大模型面试常见的面试题,希望对大家的面试有所帮助。 往期回顾: 大模型面经 | 春招、秋招算法面试常考八股文附答案(RAG专题一) 大模型面经 | 春招、秋招算法面试常考八股文附答案(RAG专题二) 大模型面经 | 春招、秋招算法…...
【PCB工艺】推挽电路及交越失真
推挽电路(Push-Pull Circuit) 推挽电路(Push-Pull Circuit) 是一种常用于功率放大、电机驱动、音频放大等场合的电路结构,具有输出对称、效率高、失真小等优点。 什么是推挽电路? 推挽是指:由两种极性相反的器件(如 NPN 和 PNP、NMOS 和 PMOS)交替导通,一个“推”电…...
接口访问数据库报错问题记录
报错信息: java.sql.SQLException: Access denied for user rootXXX.XX.XX.XX (using password: YES) 解决方法: -- 授予 root 用户从 XXX.XX.XX.XX 访问所有数据库的权限 GRANT ALL PRIVILEGES ON *.* TO 数据库用户XX.XX.XX.XXX IDENTIFIED BY 数…...
神经网络相关内容
划分数据集以及模型定义 def data_split(datax, datay, val_size 0.1, test_size 0.05):输入:datax datay 输出:trainx, valx, testx, trainy, valy, testy, 分别按比例得到训练集、验证集、测试集# 构建数据集pos_test int(len(datax) * (1 - test_…...
python项目实战-后端个人博客系统
本文分享一个基于 Flask 框架开发的个人博客系统后端项目,涵盖用户注册登录、文章发布、分类管理、评论功能等核心模块。适合初学者学习和中小型博客系统开发。 一、项目结构 blog │ app.py │ forms.py │ models.py │ ├───instance │ blog.d…...
谷歌搜索索引编译中的重定向错误解决方案
谷歌搜索索引编译中的重定向错误解决方案 在处理谷歌搜索引擎优化(SEO)过程中遇到的重定向错误问题时,了解其根本原因并采取适当措施至关重要。以下是针对常见重定向错误及其解决方案的具体分析: 1. 滥用301和302重定向 滥用永…...
OpenCV 中的角点检测方法详解
文章目录 引言1. Harris角点检测原理1.1 什么是角点?1.2 Harris算法的核心思想1.3 角点、边缘和平坦区域的区分 2. OpenCV实现Harris角点检测3. 总结 引言 在计算机视觉和图像处理中,特征点检测(Feature Detection)是一个关键任务…...
【开源】STM32HAL库驱动ST7789_240×240(硬件SPI+软件SPI)
项目开源链接 github主页https://github.com/snqx-lqh本项目github地址https://github.com/snqx-lqh/STM32F103C8T6HalDemo作者 VXQinghua-Li7 📖 欢迎交流 如果开源的代码对你有帮助,希望可以帮我点个赞👍和收藏 项目说明 最近调试了一款1…...
区块链技术在物联网中的应用:构建可信的智能世界
在当今数字化时代,物联网(IoT)和区块链技术正成为推动科技发展的两大重要力量。物联网通过连接设备实现数据的共享和交互,而区块链则以其去中心化、不可篡改的特性,为物联网的安全性和可信度提供了强大的保障。本文将探…...
uniapp实现app自动更新
uniapp实现app自动更新: 实现步骤: 需要从后端读取最新版本的相关信息前端用户进入首页的时候,需要判断当前版本与后端返回来的版本是否一致,不一致且后端版本大于当前版本的话,就需要提示用户是否需要更新ÿ…...
智能滚动抽奖--测试报告
目录 一、项目背景 二、项目功能 三、测试计划 一)单元集成测试: 二)功能测试: 三)自动化测试: 四)存在问题 五)测试结果评估 四、总结 一、项目背景 1.随着数字营销的兴起&…...
天梯-这是字符串题
隐式转换 隐式转换是指编译器在没有显式提示的情况下,自动将一种数据类型转换为另一种数据类型。这种转换是语言规范允许的,并且通常是为了让代码更简洁、更自然。隐式转换的类型字符类型( char )可以隐式转换为其对应的ASCII码值…...
第六章 QT基础:4、QT的TCP网络编程
一、TCP 通信原理简介 TCP(Transmission Control Protocol)是一种面向连接的可靠通信协议,主要特性如下: [!NOTE] 三次握手建立连接 可靠传输:顺序、无丢包 面向流:数据无结构边界 适用场景:…...
Windows 各版本查找计算机 IP 地址指南
IP 地址是互联网协议地址 (Internet Protocol Address) 的缩写,它是分配给连接到使用互联网协议进行通信的网络的每个设备的数字标签,用于在网络中唯一标识该设备。查找您计算机的 IP 地址对于网络故障排除、配置网络设置、远程访问以及进行其他网络相关…...
程序员思维体操:TDD修炼手册
程序员思维体操:TDD修炼手册 ——从"先写代码"到"测试先行"的认知革命 一、重新认识TDD:不仅仅是写测试 什么是TDD(测试驱动开发) TDD其实很简单,不要看名字很高级复杂,传统开发是直…...
Java 实现SpringContextUtils工具类,手动获取Bean
SpringContextUtils 工具类实现 下面是一个完整的 Spring 上下文工具类实现,用于从 Spring 容器中获取 Bean。这个工具类考虑了线程安全、性能优化和易用性,并提供了多种获取 Bean 的方式。 完整实现代码 import org.springframework.beans.BeansExce…...
动态规划(一)【背包】
目录 01背包问题滚动数组优化(二维-->一维) 完全背包问题优化 多重背包二进制优化 感悟 动态规划 总而言之,就是利用 历史记录, 避免重复计算。 1.确定状态变量(函数) 2.确定状态转移方程 3.确定边界条…...
实验二 多线程编程实验
一、实验目的 1、掌握线程的概念,明确线程和进程的区别。 2、学习Linux下线程创建方法及编程。 3、了解线程的应用特点。 4、掌握用锁机制访问临界区实现互斥的方法。 5、掌握用信号量访问临界区实现互斥的方法。 6、掌握线程下用信号量实现同步操作的方法。 …...
密码学(1)LWE,RLWE,MLWE的区别和联系
一、定义与基本概念 LWE(Learning With Errors): 定义:LWE问题是在给定一个矩阵A和一个向量b^Axe(其中e是一个固定数值范围内随机采集的随机噪音向量)的情况下,求解未知的向量x。本质࿱…...
数据结构-链表
目录 一、链表的基本概念单链表定义双链表定义 二、链表的基本操作1. 创建链表2. 遍历链表3. 插入节点4. 删除节点5. 反转链表 三、链表的实际应用1. 操作系统中的内存管理2. 文件系统中的目录结构3. 浏览器历史记录 四、链表的优缺点优点缺点 五、总结 一、链表的基本概念 链…...
go中redis使用的简单介绍
目录 一、Redis 简介 二、Go中Redis的使用 1. 安装Go Redis包 2. 单机模式 连接示例 3. 哨兵模式 依赖 连接示例 三、Redis集群 1. 集群模式 集群部署 部署结构 使用redis-cli创建集群 连接示例 四、常用数据结构与操作 1. 字符串(String࿰…...
使用 JUnit 4在 Spring 中进行单元测试的完整步骤
以下是使用 JUnit 4 在 Spring 中进行单元测试的完整步骤,包含配置、核心注解、测试场景及代码示例: 1. 添加依赖 在 pom.xml 中引入必要的测试依赖(以 Spring 4/5 JUnit 4 为例): <!-- JUnit 4 --> <depe…...
第七节:进阶特性高频题-Vue3的ref与reactive选择策略
ref:基本类型(自动装箱为{ value: … }对象) reactive:对象/数组(直接解构会丢失响应性,需用toRefs) 一、核心差异对比 维度refreactive适用类型基本类型(string/number/boolean&a…...
Redis 详解:安装、数据类型、事务、配置、持久化、订阅/发布、主从复制、哨兵机制、缓存
目录 Redis 安装与数据类型 安装指南 Windows Linux 性能测试 基本知识 数据类型 String List(双向列表) Set(集合) Hash(哈希) Zset(有序集合) 高级功能 地理位置&am…...
第十篇:系统分析师第三遍——7、8章
目录 一、目标二、计划三、完成情况四、意外之喜(最少2点)1.计划内的明确认知和思想的提升标志2.计划外的具体事情提升内容和标志 五、总结 一、目标 通过参加考试,训练学习能力,而非单纯以拿证为目的。 1.在复习过程中,训练快速阅读能力、掌…...
从 Vue 到 React:React.memo + useCallback 组合技
目录 一、Vue 与 React 的组件更新机制对比二、React.memo 是什么?三、常见坑:为什么我用了 React.memo 还是会重新渲染?四、解决方案:useMemo / useCallback 缓存引用五、Vue 3 中有类似的性能控制需求吗?六、组合优化…...
1656打印路径-Floyd/图论-链表/数据结构
蓝桥账户中心 1.税收: “城市的税收”:所以是中介点的税收,经过该点后加上 2.路径: 用数组存储前驱节点从而串成链表 pre[ i ][ j ]代表的是从 i 到 j 的最短路径上 j 的前驱节点是什么 那么便可以pre[ i ][ j ]k 把k加入pa…...
Linux网络编程 从集线器到交换机的网络通信全流程——基于Packet Tracer的深度实验
这里我们先下载一个软件:Packet Tracer 用来搭建网络拓扑图的,是模拟和查看数据在网络中传输的详细过程的 在软件这里可以添加设备 知识点1【集线器】(Hub) 1、先配置一下主机的IP 这里我们设置IP一定要在同一个网段ÿ…...
深入学习Axios:现代前端HTTP请求利器
文章目录 深入学习Axios:现代前端HTTP请求利器一、Axios简介与安装什么是Axios?安装Axios 二、Axios基础使用发起GET请求发起POST请求并发请求 三、Axios高级特性创建Axios实例配置默认值拦截器取消请求 四、Axios与TypeScript五、最佳实践1. 封装Axios2…...
FANUC机器人GI与GO位置数据传输设置
FANUC机器人GI与GO位置数据传输设置(整数小数分开发) 一、概述 在 Fanuc 机器人应用中,如果 IO 点位足够,可以利用机器人 IO 传输位置数据及偏移位置数据等。 二、操作步骤 1、确认通讯软件安装 首先确认机器人控制柜已经安装…...
微服务 RabbitMQ 组件的介绍、安装与使用详解
微服务 RabbitMQ 组件的介绍、安装与使用 在现代微服务架构中,服务之间的通信通常采用消息队列的方式,来解耦服务之间的依赖、提高系统的可靠性和扩展性。RabbitMQ 作为一种高效、可靠的消息队列系统,已经广泛应用于微服务架构中。本文将介绍…...
Vue3速通笔记
Vue3入门到实战 尚硅谷Vue3入门到实战,最新版vue3TypeScript前端开发教程 1. Vue3简介 2020年9月18日,Vue.js发布版3.0版本,代号:One Piece(n经历了:4800次提交、40个RFC、600次PR、300贡献者官方发版地…...
Spring Boot 项目:如何在 JAR 运行时读取外部配置文件
在 Spring Boot 项目中,我们常常需要在生产环境中灵活地配置应用,尤其是当我们将项目打包为 JAR 文件时,如何在运行时通过外部配置文件(如 application.yml 或 application.properties)替换 JAR 内部的配置就变得尤为重…...
Certimate本地化自动化 SSL/TLS 证书管理解决方案
一、背景与挑战 多域名管理复杂 运维团队往往需要为多个子域、泛域名乃至不同项目的域名分别申请证书,手动操作容易出错且耗时。续期易忘风险 主流免费证书(如 Let’s Encrypt)有效期仅 90 天,需要定期续期,人工监控门…...