为什么你的应用OOM?jstack告诉你哪些线程正在偷偷吃光内存

第一章:为什么你的应用OOM?jstack告诉你哪些线程正在偷偷吃光内存

当Java应用突然抛出OutOfMemoryError,第一反应往往是堆内存不足。但真正的问题可能隐藏在线程行为中——某些线程在后台持续创建对象或持有大对象引用,悄然耗尽内存资源。此时,jstack 成为诊断线程级问题的利器,它能生成当前JVM的线程快照,帮助你定位“内存吞噬者”。

如何使用jstack捕获线程堆栈

通过以下命令获取目标Java进程的线程转储:
# 查找Java进程ID
jps -l

# 生成线程堆栈快照
jstack <pid> > thread_dump.log
该命令输出所有线程的调用栈,包括线程状态(如RUNNABLE、BLOCKED)、锁信息及执行路径。

识别可疑线程的关键特征

在生成的堆栈文件中,重点关注以下行为:
  • 处于 RUNNABLE 状态且持续执行循环逻辑的线程
  • 持有大量对象引用或频繁调用 new 操作的方法栈
  • 线程名异常或数量远超预期的线程组(如自定义线程池泄漏)

结合堆栈分析内存消耗模式

例如,发现某线程频繁调用以下代码:
public void cacheData(String data) {
    // 将数据添加到静态集合,未设置过期机制
    DataCache.ALL_DATA.add(data); // 可能导致内存累积
}
若该方法出现在多个活跃线程的调用栈中,且 ALL_DATA 为静态容器,则极可能是内存泄漏源头。
线程状态风险等级说明
RUNNABLE高正在执行,可能持续分配内存
WAITING低通常不主动消耗资源
BLOCKED中可能存在锁竞争,间接影响内存释放
通过定期对比多次 jstack 输出,可追踪线程行为变化趋势,精准锁定内存异常增长的根源。

第二章:深入理解jstack与线程内存行为

2.1 jstack工具原理与线程快照获取机制

jstack 是 JDK 自带的命令行工具,用于生成 Java 进程的线程快照(Thread Dump),其核心原理是通过 Attach API 附加到目标 JVM 进程,触发 VM 内部的 `Threads::print_thread_info()` 方法,遍历所有线程并输出其栈轨迹。
线程快照的生成过程
当执行 jstack 命令时,操作系统信号机制(如 Linux 的 SIGQUIT)被用来暂停目标 JVM 所有线程,确保快照一致性。随后,JVM 遍历线程列表,收集每个线程的调用栈、状态、锁信息等元数据。
jstack -l 12345 > thread_dump.txt
该命令对进程 ID 为 12345 的 Java 应用生成详细线程快照。参数 `-l` 启用长格式输出,包含额外的锁信息,有助于诊断死锁或阻塞问题。
内部通信机制
jstack 利用 JVM 的 Attach 机制建立双向通信通道。具体流程如下:
  1. 启动 AttachService 并连接目标 JVM 的套接字接口;
  2. 发送“ThreadDump”指令;
  3. 接收结构化文本响应并输出至控制台。

2.2 线程状态分类及其对内存占用的影响

线程在其生命周期中会经历多种状态,不同状态对系统资源的占用存在显著差异。理解这些状态有助于优化并发程序的性能与内存使用。
线程的主要状态
典型的线程状态包括:新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)、等待(Waiting)和终止(Terminated)。处于“运行”或“就绪”状态的线程通常保留在内存中,并持有栈空间和上下文信息。
  • 就绪/运行:线程正在CPU上执行或等待调度,占用完整线程栈(通常1MB以上);
  • 阻塞/等待:因I/O或同步锁暂停,仍驻留内存,但不参与调度;
  • 终止:线程逻辑结束,JVM需延迟释放其内存资源。
内存影响对比
状态栈内存占用堆引用可被GC回收?
新建 / 就绪 / 运行高是否
阻塞 / 等待高是否
终止低(待清理)可能残留是(延迟)

// 示例:创建并启动线程观察状态变化
Thread thread = new Thread(() -> {
    try {
        Thread.sleep(1000); // 阻塞状态
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
});
System.out.println(thread.getState()); // NEW
thread.start();
System.out.println(thread.getState()); // RUNNABLE(可能)
上述代码演示了线程状态的动态变化。调用 start() 后,线程进入就绪或运行状态(表现为RUNNABLE),随后在 sleep() 期间进入阻塞状态。尽管此时不消耗CPU,其栈内存仍被保留,直到运行结束并由GC逐步回收。

2.3 如何通过线程栈识别潜在的内存泄漏源头

线程栈记录了方法调用的完整路径,是定位内存泄漏的重要线索。通过分析栈帧中长期存在的对象引用,可发现未被及时释放的资源。
关键步骤解析
  • 捕获运行时线程栈快照
  • 识别频繁出现或异常增长的对象引用链
  • 结合堆转储(Heap Dump)定位具体实例
示例:Java 线程栈中的可疑引用

Thread-0 (RUNNABLE)
  at com.example.CacheService.put(CacheService.java:45)
  at com.example.DataLoader.load(DataLoader.java:32)
  // 此处持有一个静态缓存引用,可能导致内存泄漏
上述栈信息显示 CacheService.put() 被频繁调用,若其内部使用静态集合存储对象且无过期机制,则可能形成内存泄漏源头。
常见泄漏模式对照表
调用栈特征可能原因
频繁进入缓存写入方法未限制大小的缓存
监听器注册未注销事件订阅未清理

2.4 实战:使用jstack捕获高内存场景下的线程堆栈

在Java应用出现高内存占用时,线程状态异常往往是潜在原因。通过`jstack`可捕获线程堆栈,定位阻塞或死锁线程。
操作步骤
  1. 使用jps查找目标Java进程ID
  2. 执行jstack <pid>输出堆栈信息
  3. 重点关注WAITING、BLOCKED状态线程
jstack 12345 > thread_dump.log
该命令将进程12345的线程堆栈导出至文件,便于离线分析。BLOCKED线程若持续增长,可能暗示锁竞争问题。
结合内存分析定位根因
线程状态常见原因
BLOCKED等待进入synchronized块
WAITING调用Object.wait()或Thread.join()
配合jmap生成堆转储,可交叉验证是否存在大对象导致GC压力,进而引发线程堆积。

2.5 分析输出:定位持续增长的调用栈与异常线程

在性能分析过程中,持续增长的调用栈和异常线程是系统潜在瓶颈的重要信号。通过分析运行时堆栈,可识别长时间运行或递归调用的方法。
关键线程堆栈采样

// 示例:从线程转储中提取的异常增长调用栈
Thread [Worker-Pool-Thread-3] (RUNNABLE):
    at com.example.service.DataProcessor.process(DataProcessor.java:124)
    at com.example.service.DataProcessor.lambda$submitTask$0(DataProcessor.java:88)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
    at java.util.concurrent.FutureTask.run(FutureTask.java:264)
该线程处于 RUNNABLE 状态,但持续占用 CPU,process() 方法位于调用栈顶端,提示其为性能热点。
异常线程分类统计
线程状态数量可能原因
BLOCKED15锁竞争激烈
RUNNABLE8CPU 密集型任务
WAITING22资源未就绪

第三章:常见导致内存溢出的线程模式

3.1 死锁线程与资源等待导致的内存堆积

当多个线程相互持有对方所需的资源并持续等待时,系统进入死锁状态。此时线程无法释放已占用的内存资源,导致对象无法被回收,最终引发内存堆积。
典型死锁场景示例

synchronized (resourceA) {
    // 持有 resourceA
    Thread.sleep(100);
    synchronized (resourceB) {  // 等待 resourceB
        // 执行操作
    }
}
上述代码若被两个线程交叉执行,可能形成 A→B 和 B→A 的循环等待链,造成线程阻塞。
资源等待对内存的影响
  • 阻塞线程保留栈帧和局部变量,增加堆内存压力
  • 等待期间创建的临时对象延迟回收
  • 线程本地存储(ThreadLocal)未清理将导致内存泄漏
通过监控线程堆栈和内存使用趋势,可有效识别此类问题。

3.2 无限循环或递归调用引发的栈内存耗尽

当函数递归调用缺乏有效终止条件时,每次调用都会在调用栈中新增一个栈帧,持续消耗栈空间,最终导致栈溢出(Stack Overflow)。
典型递归错误示例
func badRecursion(n int) {
    fmt.Println(n)
    badRecursion(n + 1) // 缺少退出条件
}
上述代码未设置基础情形(base case),导致无限递归。随着调用深度增加,栈帧不断堆积,最终触发运行时异常。
预防措施与优化策略
  • 确保每个递归函数包含明确的终止条件
  • 优先使用迭代替代深层递归以降低栈压力
  • 合理控制递归深度,必要时引入记忆化技术减少重复调用
通过合理设计调用逻辑,可有效避免因栈空间耗尽导致的程序崩溃。

3.3 线程局部变量(ThreadLocal)滥用造成的内存泄露

ThreadLocal 的基本机制
ThreadLocal 为每个线程提供独立的变量副本,常用于避免多线程竞争。其内部通过 ThreadLocalMap 存储数据,键为当前 ThreadLocal 实例的弱引用。
内存泄露的根本原因
当线程生命周期较长(如线程池中的线程),而 ThreadLocal 变量未被及时清理时,ThreadLocalMap 中的条目无法被自动回收。尽管 key 是弱引用,但 value 仍为强引用,导致内存累积。
  • ThreadLocal 使用不当常见于 Web 应用中请求结束后未调用 remove()
  • 线程复用加剧了该问题,value 长期驻留内存
private static final ThreadLocal<String> context = new ThreadLocal<>();

public void process() {
    context.set("long-running-data");
    try {
        // 业务逻辑
    } finally {
        context.remove(); // 必须手动清除,防止内存泄露
    }
}
上述代码中,remove() 调用是关键。若缺失,当前线程后续即使不再使用该变量,value 仍存在于 ThreadLocalMap 中,最终引发内存泄露。

第四章:结合JVM内存模型进行综合诊断

4.1 将jstack输出与堆转储(heap dump)关联分析

在排查Java应用的性能瓶颈或死锁问题时,单独分析线程栈(jstack)或堆内存(heap dump)往往难以定位根本原因。结合两者可精准识别如内存泄漏导致的线程阻塞等问题。
关联分析的核心思路
通过线程ID建立jstack与堆转储之间的映射关系。重点关注处于BLOCKED、WAITING状态的线程,并在其堆栈中查找持有大对象或大量对象引用的线程。
示例:定位阻塞线程的内存根源

# 获取线程dump
jstack -l <pid> > thread_dump.log

# 获取堆转储
jmap -dump:format=b,file=heap.hprof <pid>
上述命令分别生成线程快照和堆内存镜像。使用VisualVM或Eclipse MAT加载二者,筛选出阻塞线程ID,在堆转储中反向查找其持有的对象引用链。
线程状态可能成因对应堆分析重点
BLOCKED竞争锁被占用持有锁对象的线程及其保留集
WAITING等待通知或条件等待队列中的对象实例大小

4.2 识别持有大量对象引用的可疑线程栈帧

在排查Java应用内存问题时,某些线程可能因持有大量对象引用而成为内存泄漏的根源。通过分析线程转储(Thread Dump)中的栈帧,可定位异常行为。
关键分析步骤
  • 导出应用的线程转储文件(如使用 jstack 工具)
  • 查找处于 RUNNABLE 或 BLOCKED 状态的线程
  • 检查其调用栈中是否存在频繁创建对象的方法调用
示例代码片段

public void processData() {
    List<Object> cache = new ArrayList<>();
    while (true) {
        cache.add(new LargeObject()); // 持续添加未释放的对象
    }
}
上述代码在单个线程中不断向局部集合添加大对象,导致该栈帧间接持有多达数千个对象引用,GC无法及时回收。
识别特征表
特征说明
栈深度异常某帧调用层次过深,可能隐含循环引用
本地变量持有多量对象Local variable table 中引用数超过阈值

4.3 利用MAT或Arthas辅助定位内存热点线程

在排查Java应用内存异常时,定位内存热点线程是关键步骤。MAT(Memory Analyzer Tool)和Arthas提供了高效手段。
MAT分析堆转储文件
通过生成堆转储文件(heap dump),使用MAT打开后可查看“Histogram”视图,按类实例数或占用内存排序,快速识别内存占用大户。结合“Dominator Tree”可定位持有大量对象的GC Root路径。
Arthas实时诊断线程内存行为
Arthas提供命令行级实时监控能力。执行以下命令可查看当前最耗内存的线程:
thread --top-n-memory 5
该命令列出内存使用最高的前5个线程,输出包括线程ID、名称及栈信息,便于关联代码逻辑。配合watch命令可追踪特定方法的对象创建行为。
  • MAT适用于离线深度分析,适合复现复杂内存泄漏场景
  • Arthas适用于生产环境实时诊断,无需重启应用

4.4 实战演练:从线上OOM事故中还原罪魁线程

在一次生产环境的突发 OutOfMemoryError(OOM)事件中,系统频繁 Full GC 但内存无法释放,初步判断存在对象泄漏。通过 jmap -histo:live <pid> 快照对比,发现某缓存类实例数量异常增长。
线程堆栈抓取与分析
使用 jstack <pid> 获取线程快照,重点排查持有大量对象引用的线程。结合日志时间戳,定位到一个定时任务线程持续向静态缓存添加数据而未清理。

// 模拟问题代码
public class CacheTask implements Runnable {
    private static Map<String, byte[]> cache = new ConcurrentHashMap<>();

    public void run() {
        String key = UUID.randomUUID().toString();
        cache.put(key, new byte[1024 * 1024]); // 每次放入1MB,无过期机制
    }
}
上述代码未设置缓存过期策略,导致对象长期存活,最终触发 OOM。
解决方案验证
引入 Guava Cache 并设置最大容量与过期时间:
  • maximumSize=1000
  • expireAfterWrite=10分钟
上线后内存增长趋势恢复正常,GC 频率显著下降。

第五章:预防与优化:构建健壮的线程管理机制

合理配置线程池参数
线程池的配置直接影响系统性能与稳定性。核心线程数应根据 CPU 核心数和任务类型设定,避免过度创建线程导致上下文切换开销。对于 I/O 密集型任务,可适当增加最大线程数。
  • 核心线程数 = CPU 核心数 + 1(适用于计算密集型)
  • 最大线程数 = 核心数 × 2(I/O 密集型可更高)
  • 使用有界队列防止资源耗尽,如 LinkedBlockingQueue 并设置容量
监控线程状态与异常处理
未捕获的线程异常可能导致任务静默失败。通过设置 UncaughtExceptionHandler 捕获并记录异常:
thread.setUncaughtExceptionHandler((t, e) -> {
    System.err.println("Thread " + t.getName() + " failed: " + e.getMessage());
});
定期导出线程 dump 分析阻塞、死锁等问题,结合 JMX 或 Micrometer 暴露线程池指标。
优雅关闭与资源释放
应用关闭时应中断正在执行的任务并清理资源。调用 shutdown() 后等待任务完成,必要时使用 awaitTermination() 设置超时:
executor.shutdown();
if (!executor.awaitTermination(30, TimeUnit.SECONDS)) {
    executor.shutdownNow();
}
避免常见陷阱
问题解决方案
线程泄漏确保每次 submit 后能正常结束,避免无限循环任务
死锁避免嵌套锁,按固定顺序获取锁资源
过度同步减少 synchronized 范围,使用 ConcurrentHashMap 替代同步集合
JVM核心知识全解析:内存模型、类加载机制与调优实战 Java程序的稳定运行离不开JVM这一底层基础设施,其核心能力体现在内存管理、类加载机制与垃圾回收等多个层面。理解运行时数据区如何划分、对象如何分配与晋升,以及类加载的双亲委派模型为什么能保障安全,是每一位后端开发者从“会写代码”走向“懂JVM”的关键。在工程实践中,合理选型垃圾收集器、配置调优参数并掌握OOM排查方法,能显著降低线上故障率。面对高并发低延迟场景,G1收集器凭借可预测的停顿时间和Region分区设计成为主流选择,而通过jstat、jmap等工具分析GC日志,则是定位内存问题的基本功。这篇文章 阅读详情

相关推荐

Java ThreadPoolExecutor七参数深度解析与生产调优

线程池是Java并发编程的核心基础设施,其底层实现ThreadPoolExecutor的7个构造参数直接决定系统稳定性与性能边界。理解corePoolSize与maximumPoolSize的数学建模逻辑、workQueue的有界性对背压控制的关键作用、以及RejectedExecutionHandler在不同业务场景下的容错语义,是构建高可用服务的基础能力。尤其在高并发、IO密集型系统中,盲目使用Executors工厂方法极易引发OOM或线程耗尽等线上故障。本文结合CPU/IO密集型任务公式、队列容量科学

weixin_30814329的博客 414

线上服务频繁OOM?,用jstack三步精准揪出内存泄露元凶

快速定位Java内存泄露问题,掌握jstack分析方法。适用于线上服务频繁OOM场景,通过三步法精准排查线程堆栈,定位泄露根源,提升系统稳定性。操作简单、实用高效,值得收藏。

SimProceed的博客 967

从程序报错到性能调优:操作系统核心机制深度解析

操作系统作为计算机系统的核心,其核心职责是管理硬件资源并为应用程序提供统一的运行环境。理解其工作原理是解决各类技术问题的基石。操作系统通过进程管理、内存管理、文件系统和网络子系统等核心机制,实现了资源的抽象、分配与隔离。在工程实践中,无论是排查“程序无法运行”的兼容性问题,还是分析“CPU使用率100%”的性能瓶颈,亦或是进行“麒麟操作系统部署”等国产化适配,都离不开对操作系统底层机制的深入理解。掌握虚拟内存、系统调用、中断处理等核心概念,能帮助开发者从根源上定位问题,例如通过分析内存交换(swap)活动或

weixin_30617737的博客 510

Arthas教你秒解GPU、内存、接口问题!提升排查效率轻松搞定!

1. Arthas是什么Arthas(阿尔萨斯)是一款由阿里巴巴开源团队开发的Java与诊断工具。它作为一种开源的Java诊断工具,主要用于在生产环境中实时监控、分析和诊断Java应用程序的性能问题。Arthas提供了一系列的,可以实时查看Java应用的运行状态、堆栈信息、方法执行耗时等关键性能数据,帮助开发者快速定位并解决问题。

weixin_53618357的博客 536

CPU占用率100%排查指南:从根因分析到实战解决

CPU使用率是衡量计算资源负载的核心指标,它反映了处理器执行任务的时间比例。当CPU占用率达到100%时,意味着计算需求超过了处理能力,系统性能将严重下降。其背后原理涉及进程调度、资源竞争与硬件瓶颈等多个层面。从技术价值看,快速定位CPU瓶颈是保障系统稳定性和用户体验的关键技能,尤其在微服务、容器化等现代架构中更为重要。常见的应用场景包括服务器性能调优、应用故障排查以及云资源优化等。本文将结合火焰图、jstack等热词,系统解析CPU满载的软件与硬件根因,并提供从监控定位到深度诊断的完整方法论,涵盖Linu

weixin_30644369的博客 347

五大经典遥感数据集对比:LoveDA、Potsdam、Toronto、Vaihingen、Massachusetts Roads选哪个?

本文深度对比了LoveDA、Potsdam、Vaihingen、Toronto和Massachusetts Roads五大经典遥感数据集。针对城市监测、道路提取、土地分类等不同任务,从分辨率、标注质量、数据规模及场景多样性等核心维度进行分析,为研究者根据项目目标、硬件条件与应用场景选择最合适的遥感数据集提供决策指南。

weixin_29057065的博客 237

java jstack dump 线程 介绍 解释(转)

hi,all:        最近抽时间把JVM运行过程中产生的一些线程进行了整理,主要是围绕着我们系统jstack生成的文件为参照依据。  前段时间因为系统代码问题,造成性能到了天花板,于是就dump了一份stack出来进行分析。  看stack其实也需要一定的经验,毕竟它里面很多线程不可能都是有问题,所以,需要对他们有一定认识。  现在市面上很少有人对这一块做整理,所以,导致很多新人在拿...

喝茶聊天 3319

2023-2024深度学习框架之争——选pytorch还是tensorflow?

深度学习是人工智能领域的一个重要分支,它利用多层神经网络来模拟人类的学习和推理能力,解决各种复杂的问题,如图像识别、自然语言处理、语音识别、推荐系统等。深度学习框架是一种软件工具,它提供了构建、训练、测试和部署深度学习模型的便利,使得开发者和研究者可以更高效地进行深度学习的开发和应用。目前,市场上有许多不同的深度学习框架,如PyTorch、TensorFlow、Keras、MXNet、Caffe2等,它们各有优劣,适用于不同的场景和需求。

flchen_nchu的博客 6756

JVM调优实战:从内存模型到GC原理,解决OOM与死锁难题

Java虚拟机(JVM)作为Java应用的核心运行环境,其内存管理与垃圾回收机制是保障应用性能与稳定性的基础。理解JVM内存模型(堆、栈、方法区)与垃圾回收原理,是进行性能调优的前提。通过合理配置堆内存参数(如-Xms、-Xmx)与选择垃圾回收器(如G1、ZGC),可以有效提升吞吐量、降低延迟,这对于高并发、大数据量场景下的应用至关重要。在实际工程实践中,内存溢出(OOM)和死锁是两类常见且棘手的问题。掌握jmap、jstack等JDK命令行工具,能够快速定位内存泄漏与线程阻塞,例如通过分析堆转储文件识别无

weixin_30770783的博客 373

MIPI DPHY接口(基于Xilinx FPGA实现)案例分析

在Xilinx FPGA实现MIPI DPHY接口的案例(包括CIS协议层)。截止目前为止,Xilinx仅在Ultrascale+及其以上版本的FPGA IO可直接支持MIPI 电平输入,其他的,都需要转换成LVDS来接收。

ONEFPGA的博客 5628

大模型训练显存瘦身全记录:从ZeRO-3参数分区到CPU Offload的硬件协奏曲

本文详细解析了如何通过ZeRO-3参数分区与CPU/NVMe卸载技术优化大模型训练的显存使用。结合bf16混合精度与梯度累积等策略,实现在消费级GPU上高效训练百亿参数模型,显著提升硬件利用率与训练效率。

weixin_29051245的博客 435

Java应用性能优化实战:JVM核心参数解析与内存问题排查指南

Java虚拟机(JVM)作为Java应用的核心运行环境,其内存管理与垃圾回收机制直接影响着应用的性能与稳定性。理解JVM内存模型与GC原理,是进行性能调优的基础。通过合理配置堆内存、元空间等关键参数,并选择合适的垃圾回收器,可以有效提升吞吐量、降低延迟。在工程实践中,面对内存溢出(OOM)、频繁Full GC等常见性能瓶颈,掌握JDK自带的jstack、jmap等诊断工具,能够快速定位问题根源,例如分析线程死锁或排查内存泄漏。本文聚焦于JVM调优的核心参数配置与实战排查技巧,为构建高可用的Java服务提供系

leonard61306500的专栏 317

Kali下RTL8812AU网卡5G抓包精准适配指南

WiFi监听模式是无线安全测试的基础能力,其核心在于网卡驱动对802.11a/n/ac协议栈的完整支持。RTL8812AU系列USB无线网卡因成本低、兼容性广被广泛用于渗透测试,但其芯片版本碎片化(如VA/VC/ACM)与Linux内核演进(6.1~6.5)存在严重适配断层,导致5GHz频段Beacon帧捕获失败、信道切换异常、注入功能残缺等典型问题。技术价值在于突破‘即插即用’幻觉,建立从USB设备ID识别、固件版本校验到射频寄存器级补丁的全链路可控流程。典型应用场景包括CTF无线赛题实战、红蓝对抗中的W

weixin_33783283的博客 762

别乱用 Java 8 的并行流了!一文看懂 ForkJoinPool 是如何把服务器搞挂的

对于涉及数据库、网络调用的 IO 密集型任务,老老实实使用手动创建线程池,并配置合适的队列大小和拒绝策略。如果你非要享受并行流的语法糖,可以使用一个“欺骗” JVM 的技巧。// 1. 定义一个专属的、隔离的线程池// 2. 将 parallelStream 包装在自定义线程池中提交try {// 耗时的数据库或网络 IO 操作});}).get();// 阻塞等待执行完成// 处理异常// 视情况决定是否关闭。

郑龙飞 928

PINN求解PDE

PINN求解Dirichlet泊松方程 泊松方程引入 −Δu=f,x∈Ω=(0,1)2-\Delta u=f,x \in \Omega=(0,1)^2−Δu=f,x∈Ω=(0,1)2 u=g,x∈∂Ωu=g,x \in \partial \Omegau=g,x∈∂Ω import torch import time import numpy as np import matplotlib.pyplot as plt import torch.nn as nn def UU(X, order,prob):

forrestguang的博客 3804

YOLOv11改进-卷积-引入小波卷积WTConv 解决多尺度小目标问题

1.首先,WTConv利用二维Haar小波变换对输入图像进行多级分解。低频分量 (LL):捕捉图像的低频信息,如整体形状或轮廓。水平高频分量 (LH):捕捉图像中的水平边缘信息。垂直高频分量 (HL):捕捉图像中的垂直边缘信息。对角线高频分量 (HH):捕捉图像的对角线细节。在每一级的小波变换中,图像被下采样(空间分辨率减半),但频率信息得到了更细的分解。递归地执行小波变换(称为多级分解)可以得到不同尺度下的频率分量。

qq_64693987的博客 1万+

Java堆与栈实战陷阱:OOM、栈溢出与JVM调优真相

堆和栈是Java内存模型的两大基石,前者管理对象生命周期并依赖GC回收,后者承载方法调用与局部变量,由CPU硬件直接调度。理解二者分工——引用存栈、对象在堆——是规避内存泄漏、StackOverflowError和虚假OOM的前提。技术价值在于精准定位性能瓶颈:堆问题常表现为GC频繁或内存缓慢增长,栈问题则体现为线程崩溃、递归失效或IDE调试异常;而元空间、直接内存等‘第三区域’更易被忽视。典型应用场景包括Spring Boot启动失败、日志框架导致的char[]爆炸、ThreadLocal引发的隐式内存泄

weixin_30421809的博客 417

从0到1用OpenClaw打造酒店收益管理系统:数据整合→AI策略迭代全链路落地实战

本文基于三亚某连锁海景酒店真实项目落地经验编写,系统上线3个月,酒店平均入住率从62%提升至80%,RevPAR(平均可售房收入)提升26%,淡季空置率降低46%,完全覆盖中小酒店全场景收益管理需求。本文配套OpenClaw全量Skill代码、工作流配置文件,可直接复用落地。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 492

【JVM】元空间内存溢出导致频繁FullGC,CPU飙高

页面卡住,查看服务器资源,CPU飙高,top -H看到线程多是GC Thread,而内存占用并不高,没有触发OOM。服务重启后,CPU降到14%,页面恢复正常。

weixin_44823875的博客 229

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

深入解析JVM堆内存:从分代设计到线上OOM排查实战

JVM堆内存是Java程序运行时对象实例的核心存储区域,其管理机制直接决定了应用性能与稳定性。基于弱分代假说,现代JVM将堆划分为年轻代(含Eden、Survivor区)和老年代,并采用不同的垃圾回收策略以优化效率。理解堆内存的分代结构、对象生命周期及GC工作原理,对于实现高效内存管理、避免性能瓶颈具有关键价值。在实际应用场景中,无论是处理编译器的堆空间不足错误,还是进行JVM调优以提升系统吞吐量,都离不开对堆内存机制的深入掌握。本文聚焦于堆内存的核心架构,并结合典型的内存溢出(OOM)案例,系统阐述如何通

weixin_34175509的博客 427

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

K6压测下Spring Cloud微服务内存暴涨:TrendSink组件问题诊断与优化实战

在微服务架构的性能测试中,内存管理是核心挑战之一,尤其在高并发场景下,不当的资源生命周期管理极易引发内存泄漏或溢出。其原理往往涉及生产者-消费者模式下的速率不匹配,当异步处理链路的消费能力无法跟上生产速度时,缓冲队列会持续积压,导致JVM堆内或堆外内存被快速耗尽。这一问题的技术价值在于,它揭示了分布式系统中背压(Backpressure)处理机制的重要性,是构建弹性、可观测系统的关键。典型的应用场景包括使用K6等工具进行压力测试时,后端服务因指标收集、日志缓冲等异步组件(如文中的TrendSink)设计缺陷

468

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Java线程池七种创建方式详解:从核心参数到生产实践避坑指南

在并发编程中,线程池是管理多线程执行、提升系统性能与稳定性的核心组件。其核心原理在于复用线程资源,通过预先创建并管理一组工作线程,避免了频繁创建和销毁线程带来的开销。线程池的技术价值在于提供了可控的并发执行能力,通过核心线程数、最大线程数、工作队列及拒绝策略等关键参数的组合,能够有效应对不同负载场景,防止资源耗尽。典型的应用场景包括Web服务器请求处理、批量数据处理、异步任务执行等。本文聚焦于Java线程池的七种创建方式,深入剖析了每种方式背后的参数配置、适用场景与潜在隐患,例如使用无界队列可能导致的**内

weixin_30644369的博客 402

Go应用在DigitalOcean Kubernetes上的韧性实践指南

在云原生环境中,'韧性(Resilience)'并非抽象概念,而是指系统在面对Pod驱逐、节点宕机、网络抖动等常见故障时,仍能维持可用性与数据一致性的工程能力。其核心原理在于对资源生命周期的精确控制——从编译期符号保留与CGO行为约束,到启动阶段的三重就绪校验(容器启动、进程存活、服务可用),再到运行时goroutine治理、内存水位熔断与SIGTERM优雅退出。技术价值体现在降低MTTR、避免数据丢失、提升SLA可信度;典型应用场景包括支付回调服务、实时日志Worker及SaaS微服务。本文聚焦Go语言特

512

Java最长回文子串的工程化实现与JVM级优化

最长回文子串是字符串处理中的经典问题,其本质在于识别具有中心对称特性的连续字符序列。从算法原理看,中心扩展法以O(n²)时间复杂度平衡了性能与可维护性;在Java工程实践中,String不可变性、substring内存行为、JDK版本差异及Unicode代理对处理等底层机制,直接决定方案是否具备生产就绪能力。该问题的技术价值不仅在于算法选型,更在于驱动开发者深入理解JVM内存模型、HotSpot JIT优化策略与高并发安全设计。典型应用场景涵盖内容审核中的恶意词检测、金融流水异常识别、IoT日志结构校验等。

weixin_34258838的博客 396

接口响应慢的5大排查方向与实战技巧

本文系统梳理了接口响应慢的五大核心排查方向:硬件资源瓶颈、缓存策略、第三方依赖、SQL优化与代码质量。文章提供了从宏观到微观的实战排查技巧与命令,帮助开发者建立清晰的排查心智模型,快速定位性能瓶颈,有效提升系统响应速度。

kappa的博客 370

Java性能调优实战:JVM核心参数配置与垃圾收集器选型指南

Java虚拟机(JVM)作为Java应用的运行时引擎,其内存管理与垃圾回收机制是保障应用性能与稳定的基石。理解JVM内存模型与垃圾收集原理,是进行有效性能调优的前提。通过合理配置堆内存、元空间等关键参数,可以优化内存使用效率,避免OutOfMemoryError等常见问题。不同的垃圾收集器,如并行收集器(Parallel GC)、G1收集器(Garbage-First)以及新一代的ZGC,各自针对吞吐量、延迟等不同技术目标进行设计,适用于从批处理到高并发在线服务的多样化应用场景。掌握这些核心参数的配置逻辑与

weixin_33743880的博客 430
上一篇: Flask项目重构必看:url_prefix多级嵌套的3种模式及性能影响分析
下一篇: 揭秘synchronized锁升级全过程:偏向锁何时启用?这5个条件你必须掌握
CompiTide
博客等级 码龄1年 174粉丝 2175原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值