JVM 生产环境问题定位与解决实战(七):实战篇——OSSClient泄漏引发的FullGC风暴

在这里插入图片描述

本文已收录于《JVM生产环境问题定位与解决实战》专栏,完整系列见文末目录

引言

在前六篇博客中,我们系统性地学习了 JVM 生产环境问题定位与解决的全套工具链,涵盖jpsjmapjstatjstackjcmd 等基础工具的使用技巧,深入剖析了JConsoleVisualVMMAT 的高级应用场景,探索了JFRJMC的性能分析能力,并解锁了Arthas的在线诊断黑科技。为使读者能将理论知识转化为实战能力,笔者将分享三个真实的线上疑难案例:

  1. OSSClient 未关闭导致的内存泄漏和 CPU 飙升(本篇详解)
  2. 正则表达式回溯导致的 CPU 100%
  3. 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 报告能快速识别潜在的内存泄漏点,因此首先运行此报告。
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相关。
Histogram

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
在这里插入图片描述
查看 IdleConnectionReaperThread 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

引用关系显示 DefaultServiceClientPoolingHttpClientConnectionManager 相关,但需要通过源码确认其如何创建和管理这些对象,因此分析 DefaultServiceClient 源码。
在这里插入图片描述
查看 DefaultServiceClient 源码,发现其在构造时调用 IdleConnectionReaper.registerConnectionManager(),在 shutdown() 方法中调用 IdleConnectionReaper.removeConnectionManager().
得出结论:项目中创建了大量 DefaultServiceClient 实例,但未调用 shutdown() 方法释放资源.
在这里插入图片描述

Step 9-代码溯源(Arthas热诊断)

问题定位的难点:DefaultServiceClient 分析确认了未调用 shutdown() 的问题,但仍需确定具体业务代码为何创建大量实例,尤其是在系统长期稳定后突然触发问题,因此需要进一步追踪。

至此,已基本确定问题是 OSSClient未关闭导致的资源泄漏,但需要进一步定位具体业务代码。MAT 分析显示 PoolingHttpClientConnectionManager DefaultServiceClientGC 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%及请求延迟。

优化建议

  1. 正确释放资源:确保在使用OSSClient后调用shutdown()。推荐使用try-finallytry-with-resources(若SDK支持AutoCloseable)

    OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    try {ossClient.putObject(bucketName, key, new File("file.txt"));
    } finally {ossClient.shutdown();
    }
    
  2. 单例模式优化:如果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 实例。
    在这里插入图片描述
实验环境与流程
  1. 环境设置
    • 项目启动时启用 JVM GC 日志,配置参数为: -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseSerialGC
    • 使用 jvisualvm 工具连接到 Java 进程进行监控。
    • 使用 JMeter 进行1000次并发请求。
  2. 测试流程
    • 对三种方法(createOSSClientcreateOSSClient1createOSSClient2)分别进行 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]
    
    • 可视化证据:

结论

实验结果验证了问题分析和优化建议的正确性:

  1. 不调用shutdown()会导致内存泄漏:PoolingHttpClientConnectionManager等关键组件无法回收
  2. 正确调用shutdown()可解决问题:所有资源都能被GC正常回收
  3. 单例模式是更优方案:既能避免资源泄漏,又能减少重复创建开销

建议在实际项目中:

  • 对于短期使用的OSSClient,必须使用try-finally保证关闭
  • 对于频繁使用的场景,推荐使用单例模式管理
  • 定期监控JVM内存和GC情况,及早发现潜在问题

附录:系列目录

  1. JVM生产环境问题定位与解决实战(一):掌握jps、jmap、jstat、jstack、jcmd等基础工具
  2. JVM生产环境问题定位与解决实战(二):JConsole、VisualVM到MAT的高级应用
  3. JVM生产环境问题定位与解决实战(三):揭秘Java飞行记录器(JFR)的强大功能
  4. JVM生产环境问题定位与解决实战(四):使用JMC进行JFR性能分析指南
  5. JVM生产环境问题定位与解决实战(五):Arthas——不可错过的故障诊断利器
  6. JVM生产环境问题定位与解决实战(六):总结篇——问题定位思路与工具选择策略
  7. ➡️ 当前:JVM 生产环境问题定位与解决实战(七):实战篇——OSSClient泄漏引发的FullGC风暴

🔥 下篇预告:《JVM 生产环境问题定位与解决实战(八):实战篇——正则表达式回溯导致的 CPU 100%》
🚀 关注作者,获取实时更新通知!有问题欢迎在评论区交流讨论~

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

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

相关文章

Spark集群搭建-spark-local

&#xff08;一&#xff09;安装Spark 安装Spark的过程就是下载和解压的过程。接下来的操作&#xff0c;我们把它上传到集群中的节点&#xff0c;并解压运行。 1.启动虚拟机 2.通过finalshell连接虚拟机&#xff0c;并上传安装文件到 /opt/software下 3.解压spark安装文件到/op…

Java 异常 SSLException: fatal alert: protocol_version 全解析与解决方案

在 Java 网络通信中&#xff0c;SSLException: fatal alert: protocol_version 是典型的 TLS/SSL 协议版本不兼容异常。本文结合 Java 官方规范、TLS 协议标准及实战经验&#xff0c;提供体系化解决方案&#xff0c;帮助开发者快速定位并解决协议版本冲突问题。 一、异常本质&…

虚拟列表技术深度解析:原理、实现与性能优化实战

虚拟列表技术深度解析&#xff1a;原理、实现与性能优化实战 引言 在当今数据驱动的互联网应用中&#xff0c;长列表渲染已成为前端开发的核心挑战。传统的一次性全量渲染方式在数据量超过千条时&#xff0c;往往导致页面卡顿、内存飙升等问题。虚拟列表&#xff08;Virtual L…

2025-04-20 李沐深度学习4 —— 自动求导

文章目录 1 导数拓展1.1 标量导数1.2 梯度&#xff1a;向量的导数1.3 扩展到矩阵1.4 链式法则 2 自动求导2.1 计算图2.2 正向模式2.3 反向模式 3 实战&#xff1a;自动求导3.1 简单示例3.2 非标量的反向传播3.3 分离计算3.4 Python 控制流 硬件配置&#xff1a; Windows 11Inte…

Redis的使用总结

Redis 核心使用场景 缓存加速 高频访问数据缓存&#xff08;如商品信息、用户信息&#xff09; 缓解数据库压力&#xff0c;提升响应速度 会话存储 分布式系统共享 Session&#xff08;替代 Tomcat Session&#xff09; 支持 TTL 自动过期 排行榜/计数器 实时排序&#x…

富文本编辑器实现

&#x1f3a8; 富文本编辑器实现原理全解析 &#x1f4dd; 基本实现路径图 #mermaid-svg-MO1B8a6kAOmD8B6Y {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-MO1B8a6kAOmD8B6Y .error-icon{fill:#552222;}#mermaid-s…

LeetCode热题100——283. 移动零

给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 示例 1: 输入: nums [0,1,0,3,12] 输出: [1,3,12,0,0] 示例 2: 输入: nums [0] 输出:…

与Ubuntu相关命令

windows将文件传输到Ubuntu 传输文件夹或文件 scp -r 本地文件夹或文件 ubuntu用户名IP地址:要传输到的文件夹路径 例如&#xff1a; scp -r .\04.py gao192.168.248.129:/home/gao 如果传输文件也可以去掉-r 安装软件 sudo apt-get update 更新软件包列表 sudo apt insta…

Kafka 在小流量和大流量场景下的顺序消费问题

一、低流量系统 特点 消息量较少&#xff0c;吞吐量要求低。系统资源&#xff08;如 CPU、内存、网络&#xff09;相对充足。对延迟容忍度较高。 保证顺序消费的方案 单分区 单消费者 将消息发送到单个分区&#xff08;例如固定 Partition 0&#xff09;&#xff0c;由单个…

小程序 GET 接口两种传值方式

前言 一般 GET 接口只有两种URL 参数和路径参数 一&#xff1a;URL 参数&#xff08;推荐方式&#xff09; 你希望请求&#xff1a; https://serve.zimeinew.com/wx/products/info?id5124接口应该写成这样&#xff0c;用 req.query.id 取 ?id5124&#xff1a; app.get(&…

小白学习java第14天(中):数据库

1.DML data manage language数据库管理语言 外键:外键是什么&#xff1f;就是对其进行表与表之间的联系&#xff0c;就是使用的键进行关联&#xff01; 方法一&#xff1a;我们在数据库里面就对其进行表与表之间的连接【这种是不建议的&#xff0c;我不太喜欢就是将数据里面弄…

NO.95十六届蓝桥杯备战|图论基础-单源最短路|负环|BF判断负环|SPFA判断负环|邮递员送信|采购特价产品|拉近距离|最短路计数(C++)

P3385 【模板】负环 - 洛谷 如果图中存在负环&#xff0c;那么有可能不存在最短路。 BF算法判断负环 执⾏n轮松弛操作&#xff0c;如果第n轮还存在松弛操作&#xff0c;那么就有负环。 #include <bits/stdc.h> using namespace std;const int N 2e3 10, M 3e3 1…

K8s pod 应用

/** 个人学习笔记&#xff0c;如有问题欢迎交流&#xff0c;文章编排和格式等问题见谅&#xff01; */ &#xff08;1&#xff09;编写 pod.yaml 文件 pod 是 kubernetes 中最小的编排单位&#xff0c;一个 pod 里包含一个或多个容器。 apiVersion: v1 # 指定api版本 kind…

Oracle创建触发器实例

一 创建DML 触发器 DML触发器基本要点&#xff1a; 触发时机&#xff1a;指定触发器的触发时间。如果指定为BEFORE&#xff0c;则表示在执行DML操作之前触发&#xff0c;以便防止某些错误操作发生或实现某些业务规则&#xff1b;如果指定为AFTER&#xff0c;则表示在执行DML操作…

Filename too long 错误

Filename too long 错误表明文件名超出了文件系统或版本控制系统允许的最大长度。 可能的原因 文件系统限制 不同的文件系统对文件名长度有不同的限制。例如&#xff0c;FAT32 文件名最长为 255 个字符&#xff0c;而 NTFS 虽然支持较长的文件名&#xff0c;但在某些情况下也…

网络不可达network unreachable问题解决过程

问题&#xff1a;访问一个环境中的路由器172.16.1.1&#xff0c;发现ssh无法访问&#xff0c;ping发现回网络不可达 C:\Windows\System32>ping 172.16.1.1 正在 Ping 172.16.1.1 具有 32 字节的数据: 来自 172.16.81.1 的回复: 无法访问目标网。 来自 172.16.81.1 的回复:…

Python设计模式:备忘录模式

1. 什么是备忘录模式&#xff1f; 备忘录模式是一种行为设计模式&#xff0c;它允许在不暴露对象内部状态的情况下&#xff0c;保存和恢复对象的状态。备忘录模式的核心思想是将对象的状态保存到一个备忘录对象中&#xff0c;以便在需要时可以恢复到之前的状态。这种模式通常用…

Python基础语法3

目录 1、函数 1.1、语法格式 1.2、函数返回值 1.3、变量作用域 1.4、执行过程 1.5、链式调用 1.6、嵌套调用 1.7、函数递归 1.8、参数默认值 1.9、关键字参数 2、列表 2.1、创建列表 2.2、下标访问 2.3、切片操作 2.4、遍历列表元素 2.5、新增元素 2.6、查找元…

JavaEE学习笔记(第二课)

1、好用的AI代码工具cursor 2、Java框架&#xff1a;Spring(高级框架)、Servelt、Struts、EJB 3、Spring有两层含义&#xff1a; ①Spring Framework&#xff08;原始框架&#xff09; ②Spring家族 4、Spring Boot(为了使Spring简化) 5、创建Spring Boot 项目 ① ② ③…

基于Flask与Ngrok实现Pycharm本地项目公网访问:从零部署

目录 概要 1. 环境与前置条件 2. 安装与配置 Flask 2.1 创建虚拟环境 2.2 安装 Flask 3. 安装与配置 Ngrok 3.1 下载 Ngrok 3.2 注册并获取 Authtoken 4. 在 PyCharm 中创建 Flask 项目 5. 运行本地 Flask 服务 6. 启动 Ngrok 隧道并获取公网地址 7. 完整示例代码汇…