Java开发者必看:5种OOM错误排查与优化实战(附代码示例)

线上OOM,怎么排查? 当JVM因为没有足够的内存来为对象分配空间,并且垃圾回收器也已经没有空间可回收时,就会抛出这个错误。和不带的输出,若某类实例数差异大,说明其对象生命周期短,可能存在临时对象过多的问题。JVM因内存不足无法为对象分配空间,且垃圾回收器无法回收内存时抛出的错误。)若占用内存过高,可能未释放流、缓存或集合对象。:查看JVM内存分配及使用情况,判断是否内存分配不合理。直接内存(NIO使用的堆外内存)耗尽,常见于未释放的。:列出内存中对象实例数量及占用内存排序,定位异常对象。(Eden与Survivor区比例)。 阅读详情

Java内存深度探险:从OOM迷雾到性能绿洲的实战指南

如果你在Java世界里摸爬滚打了一段时间,大概率已经和那个令人头疼的“OutOfMemoryError”打过照面。它不像空指针那样直白,也不像逻辑错误那样容易追踪,更像一个潜伏在系统深处的幽灵,总是在你最意想不到的时候——比如大促流量洪峰、深夜批量任务、或者一次看似平常的版本上线后——突然现身,留下一片狼藉的日志和焦头烂额的你。对于中高级开发者而言,解决OOM问题早已超越了简单的“增加内存”范畴,它是一场对JVM内存模型、垃圾回收机制、乃至应用架构设计的深度考验。这篇文章不会给你一堆枯燥的理论和标准答案,而是想和你一起,像侦探一样,拿起不同的“放大镜”和“试剂”,深入五种典型OOM场景的现场,还原问题本质,并找到那些真正能落地、能复用的优化策略与代码实践。我们的目标不是记住错误类型,而是构建一套属于自己的内存问题排查与防御体系。

1. 堆内存溢出:对象洪水的治理艺术

堆是OOM最经典的“案发现场”。当看到java.lang.OutOfMemoryError: Java heap space时,我们面对的往往是一场由失控的对象创建引发的“洪水”。但原因远不止“内存不够”这么简单。

核心矛盾在于对象生命周期与GC效率的失衡。 你可以想象堆内存是一个不断周转的仓库。健康的状态是货物(对象)有进有出,周转顺畅。而溢出则意味着:要么进货太快太多(瞬时创建大量对象),要么大量货物成了无法处理的“死库存”(内存泄漏),要么仓库管理本身效率低下,清运垃圾(GC)的速度跟不上。

排查这类问题,第一步是拿到“现场快照”。jmap -dump:live,format=b,file=heap.bin <pid> 命令可以生成堆转储文件。但更高效的方式往往是在启动参数中预先埋好“自动导出手柄”:-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/dumps。这样,OOM发生时,JVM会自动保存那一刻的堆内存镜像。

用MAT或VisualVM打开dump文件,我们通常会关注几个关键视图:

  • Dominator Tree(支配树):快速定位哪些对象持有了最多的内存。
  • Histogram(直方图):按类统计对象数量和总大小,一眼看出哪个类的实例是“内存大户”。
  • Leak Suspects(泄漏嫌疑):MAT提供的自动分析报告,经常能直接给出可疑的引用链。

实战中,我遇到最多的不是“大对象”,而是“中对象”的无限累积。 例如,一个不当设计的缓存,使用了ConcurrentHashMap却从未设置过期策略或大小限制,随着时间推移,缓存条目只增不减。又或者,在Web应用中,将大量用户会话级别的数据存储在HttpSession中且未及时清理。

来看一个更隐蔽的场景:“静态集合”引起的内存泄漏。

public class LeakyClass {
    // 静态Map,生命周期与类本身一致,常被误用作“全局缓存”
    private static final Map<String, Object> CACHE = new HashMap<>();

    public void processUserData(String userId, Object data) {
        // 业务逻辑...
        CACHE.put(userId, data); // 数据被放入静态Map,除非显式移除,否则永不释放
        // 更多业务逻辑...
    }
}

这段代码的危险在于,CACHE是静态的,其引用对象永远不会被GC回收。随着processUserData被不断调用,CACHE会无限制增长。优化方案是引入一个具有容量限制和过期策略的专业缓存库,如Caffeine或Guava Cache。

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;

public class SafeCacheClass {
    // 使用Caffeine构建一个最大容量10000,写入10分钟后过期的缓存
    private static final Cache<String, Object> SAFE_CACHE = Caffeine.newBuilder()
            .maximumSize(10_000)
            .expireAfterWrite(10, TimeUnit.MINUTES)
            .build();

    public void processUserData(String userId, Object data) {
        // 业务逻辑...
        SAFE_CACHE.put(userId, data); // 超出容量或过期后会自动清理
        // 更多业务逻辑...
    }
}

除了内存泄漏,不合理的对象创建模式也是凶手。例如,在循环体内拼接字符串(String在Java中是不可变的,每次+操作都可能产生新对象),或者频繁地创建SimpleDateFormat等线程不安全的工具类实例。对于后者,推荐使用ThreadLocal为每个线程缓存一个实例,或者直接切换到java.time包下的线程安全类。

提示:在分析堆dump时,关注那些“意外长寿”的对象。一个在业务逻辑上应该是短生命周期的对象(如一次API请求的中间DTO),如果大量出现在老年代,就需要深究其引用链,看是否被某个全局性的容器“意外扣押”了。

2. 元空间溢出:类加载的“边界战争”

java.lang.OutOfMemoryError: Metaspace 将我们带入了方法区的战场。自从Java 8用元空间(Metaspace)取代永久代(PermGen),这个区域的内存管理就从JVM转移到了本地内存,默认情况下只受限于操作系统可用内存。但这并不意味着可以高枕无忧,无限制的类加载行为同样会拖垮它。

元空间存储的是类的元数据:类名、方法信息、字段信息、常量池、静态变量等。导致其膨胀的元凶,往往是动态类生成和类加载器泄漏。

动态类生成在框架中极为常见。Spring AOP使用CGLIB或JDK动态代理为Bean创建子类;MyBatis为每个Mapper接口生成代理实现类;一些RPC框架(如早期的Dubbo)也会动态生成存根(Stub)类。在应用频繁重启、或者大量使用基于原型的Bean作用域(prototype)时,这些类可能被源源不断地创建并加载。

更棘手的是类加载器泄漏。在复杂的应用服务器(如Tomcat)或插件化架构中,每个Web应用或插件通常拥有独立的ClassLoader(如ParallelWebappClassLoader)。当应用被卸载(undeploy)时,如果该ClassLoader实例仍被某个全局对象(如线程池中的线程、静态Map)引用,那么它以及它加载的所有类都无法被回收,造成元空间内存的持续占用。

排查元空间问题,jstat -gc <pid> 命令可以观察MC(Metaspace Capacity)和MU(Metaspace Utilization)的变化趋势。但更精细的分析需要借助能够转储类加载器信息的工具,比如通过jcmd <pid> GC.class_stats(需要开启-XX:+UnlockDiagnosticVMOptions)来获取统计信息,或者使用-XX:+TraceClassLoading -XX:+TraceClassUnloading来观察类的加载与卸载日志。

一个典型的类加载器泄漏案例发生在线程池配置不当的情况下:

public class LeakyPluginManager {
    private final ExecutorService executor = Executors.newFixedThreadPool(10);

    public void initPlugin(Plugin plugin) {
        // 使用当前线程的上下文类加载器(可能是WebAppClassLoader)来执行任务
        executor.submit(() -> {
            Thread.currentThread().setContextClassLoader(plugin.getClass().getClassLoader());
            plugin.start();
        });
    }
}

在这个场景中,线程池的核心线程是长期存活的。如果plugin是由一个独立的ClassLoader加载的,而该任务又通过setContextClassLoader将这个ClassLoader设置到了线程上下文中,那么这个ClassLoader就被一个长生命周期的线程(池)强引用,导致无法卸载。

优化策略是避免在长生命周期对象中持有或传播短生命周期ClassLoader的引用。对于必须使用自定义类加载器的场景,确保有明确的卸载机制,比如在任务执行完毕后清理线程上下文类加载器。

public class SafePluginManager {
    private final ExecutorService executor = Executors.newFixedThreadPool(10);

    public void initPlugin(Plugin plugin) {
        executor.submit(() -> {
            ClassLoader originalCl = Thread.currentThread().getContextClassLoader();
            try {
                Thread.currentThread().setContextClassLoader(plugin.getClass().getClassLoader());
                plugin.start();
            } finally {
                // 无论如何,在任务结束时恢复原始的类加载器
                Thread.currentThread().setContextClassLoader(originalCl);
            }
        });
    }
}

此外,合理设置元空间参数也至关重要:

  • -XX:MaxMetaspaceSize=256m:设置元空间上限,防止其无限膨胀拖累整个系统。
  • -XX:MetaspaceSize=64m:设置初始阈值,达到后触发Full GC进行类卸载尝试。
  • -XX:+UseConcMarkSweepGC 或 -XX:+UseG1GC:相比Parallel GC,CMS和G1在元空间回收上通常更积极。

3. 栈溢出与线程内存耗尽:深递归与线程池的陷阱

栈内存错误有两种常见面孔:StackOverflowError和OutOfMemoryError: unable to create native thread。前者是单个线程的调用栈太深,后者是创建的线程总数太多,耗尽了进程的虚拟内存或系统资源。

StackOverflowError 几乎是递归调用的“专利”。但现代开发中,显式的无限递归已不多见,更多是间接的、由框架或复杂调用链引发的深度调用。例如,在ORM框架(如Hibernate)中,双向关联的对象在序列化(如Jackson)时如果没有妥善处理,可能产生循环引用,导致序列化过程在递归调用中越陷越深。又或者,在复杂的业务规则引擎中,规则之间相互触发。

排查此类问题,线程转储(Thread Dump)是利器。通过jstack <pid>或发送kill -3 <pid>信号,可以获取所有线程的调用栈。在输出中搜索重复出现的相同方法调用序列,就能快速定位递归点。

OutOfMemoryError: unable to create native thread 则是一个更系统级的问题。每个Java线程都需要在JVM堆外分配一个原生线程栈(大小由-Xss参数指定,默认通常1MB)。当线程数过多,累计所需的内存超过了进程的地址空间限制(在32位系统中尤其明显)或操作系统的用户级进程线程数限制(如Linux的ulimit -u),就会抛出此错误。

罪魁祸首常常是配置不当的线程池。 例如,使用Executors.newCachedThreadPool()而不加任何约束,在突发高并发下,它可能会创建大量线程。或者,在微服务架构中,每个服务客户端(如HTTP连接池、RPC客户端)都自带一个线程池,多个服务相互调用,容易形成线程数的乘法效应。

线程池类型潜在风险推荐替代方案
newCachedThreadPool无线程数上限,可能耗尽资源newFixedThreadPool 或 newThreadPoolExecutor 自定义
newFixedThreadPool(n)任务队列无界,可能积压大量任务导致OOM使用有界队列,并定义拒绝策略
newSingleThreadExecutor任务队列无界,同上使用有界队列

一个健壮的线程池配置应该考虑以下几点:

  1. 核心与最大线程数:根据业务类型(CPU密集型、IO密集型)合理设置。
  2. 任务队列:使用有界队列(如ArrayBlockingQueue),避免无界队列导致的内存增长。
  3. 拒绝策略:当队列满且线程数达到最大值时,定义合理的拒绝策略(如CallerRunsPolicy让调用者线程执行,或记录日志后丢弃)。
  4. 线程回收:为线程设置合理的名称和allowCoreThreadTimeOut(true),方便监控和空闲回收。
// 一个更安全的线程池创建示例
ThreadPoolExecutor safeExecutor = new ThreadPoolExecutor(
    5, // 核心线程数
    20, // 最大线程数
    60L, TimeUnit.SECONDS, // 空闲线程存活时间
    new ArrayBlockingQueue<>(100), // 有界队列,容量100
    new ThreadFactoryBuilder().setNameFormat("safe-pool-%d").build(), // 命名线程
    new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略:由调用者线程执行
);

4. 直接内存溢出:NIO的“隐形”消耗

直接内存(Direct Memory)的OOM错误信息通常是OutOfMemoryError: Direct buffer memory。这部分内存不由JVM的垃圾回收器管理,而是通过ByteBuffer.allocateDirect()或NIO的FileChannel.map()等方法在堆外直接分配,其释放依赖于DirectByteBuffer对象本身的finalize机制或显式调用Cleaner。

直接内存的优势在于避免了Java堆与本地堆之间的数据拷贝,在涉及大量I/O操作(如网络传输、文件读写)时性能提升显著。 Netty、Mina等网络框架,以及一些高性能的缓存、序列化库(如Apache Arrow)都重度依赖直接内存。

问题往往出在“分配与释放的不匹配”上。 由于它不受常规GC管辖,开发者容易忽略其管理。一种情况是分配了直接内存却忘记释放。虽然DirectByteBuffer在GC时会通过Cleaner尝试回收关联的本地内存,但这个回收时机不确定,如果分配速度远超GC触发速度,就会溢出。

另一种更隐蔽的情况是JVM参数限制。直接内存的大小可以通过-XX:MaxDirectMemorySize指定,默认与Java堆的最大值(-Xmx)一致。如果你没有显式设置此参数,而应用又大量使用直接内存,就可能触顶。

排查直接内存问题,可以借助jcmd <pid> VM.native_memory命令(需开启-XX:NativeMemoryTracking=detail)来追踪详细的内存分类使用情况。在NMT的输出中,关注“Internal (committed)”部分下的“Direct”项。

来看一个使用Netty时可能遇到的场景: Netty的默认内存分配器会池化直接内存缓冲区以提高性能。但在高并发下,如果业务处理缓慢,导致缓冲区未能及时释放回池中,就可能造成池子被掏空,进而触发新的分配,最终可能超过MaxDirectMemorySize限制。

注意:直接内存的OOM可能不会立刻导致JVM崩溃,但会引发频繁的Full GC(因为JVM在无法分配直接内存时,会尝试通过Full GC来触发Cleaner工作),表现为应用间歇性卡顿。

优化直接内存使用的几点建议:

  1. 监控与限流:使用NMT监控直接内存使用趋势。为关键的直接内存分配操作(如Netty的ByteBuf分配)添加监控和限流。
  2. 合理设置参数:根据应用实际需要,通过-XX:MaxDirectMemorySize设置合理的上限。
  3. 及时释放资源:确保在使用完DirectByteBuffer或Netty的ByteBuf后,调用release()方法(如果是引用计数对象)或将引用置为null,以便GC和Cleaner能及时工作。
  4. 考虑堆内缓冲区:对于生命周期极短或大小不确定的缓冲区,评估使用堆内缓冲区(ByteBuffer.allocate())是否足以满足性能要求,以简化内存管理。

5. GC Overhead Limit Exceeded:垃圾回收的死亡螺旋

OutOfMemoryError: GC overhead limit exceeded 是一个特殊的信号,它表示JVM“自己觉得”不行了。根据Oracle官方文档,当JVM花费超过98%的总时间进行垃圾回收,并且每次回收回收到的堆内存少于2%,持续一段时间后,就会抛出此错误。这本质上是垃圾回收器陷入了“死亡螺旋”:几乎所有的CPU时间都用于GC,但每次回收都几乎无效,应用的实际业务线程几乎得不到执行时间,吞吐量降至冰点。

这通常是堆内存泄漏的晚期症状,或者是堆大小设置严重不合理(如-Xmx设置得过小,导致频繁Full GC)导致的。排查的第一步,仍然是分析堆转储,寻找泄漏点,方法同第一部分。

除此之外,GC日志是诊断此类问题的黄金标准。 务必在启动参数中开启GC日志收集:

-Xlog:gc*,gc+heap=debug,gc+age=trace:file=gc.log:time,uptime,level,tags:filecount=10,filesize=100M

或使用旧式参数(JDK 8及之前):

-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:gc.log

分析GC日志,你需要关注:

  • Full GC的频率和持续时间:频繁的、长时间的Full GC是主要嫌疑。
  • GC前后堆空间的使用率:如果每次GC后老年代使用率下降很少(比如从99.5%降到99%),那就是典型的“回收无效”。
  • 晋升到老年代的对象速率:如果年轻代对象过快晋升,可能是幸存者区(Survivor)太小或动态年龄判断机制导致。

除了内存泄漏,不合理的GC参数也可能诱发此问题。 例如,在G1垃圾回收器中,如果-XX:MaxGCPauseMillis(最大暂停时间目标)设置得过于激进(如10ms),G1为了达到这个不切实际的目标,可能会过早地启动混合回收(Mixed GC),但实际上回收效果很差,陷入不断尝试的循环。

一个综合性的优化案例: 假设一个批处理应用,需要处理一个包含百万条记录的大文件,每条记录被解析成一个Java对象进行处理。使用默认的JVM参数,可能会遇到频繁的Young GC和对象过早晋升。

优化前可能的状态:

  • 年轻代(如ParNew)很快被填满,触发频繁Minor GC。
  • 由于批处理对象生命周期近似(都在一批处理中创建和释放),大量对象在一次GC后存活,达到晋升年龄阈值,被移入老年代。
  • 老年代迅速增长,触发Full GC。

优化思路与参数调整:

  1. 增大年轻代:通过-Xmn或-XX:NewRatio增加年轻代大小,让更多对象在年轻代完成回收。
  2. 调整晋升阈值:使用-XX:MaxTenuringThreshold提高对象晋升到老年代的年龄(默认15),让对象在年轻代经历更多次GC。
  3. 调整幸存者区比例:使用-XX:SurvivorRatio调整Eden和Survivor区的比例,确保Survivor区有足够空间容纳每次GC后存活的对象。
  4. 选择合适的收集器:对于这类批处理任务,如果堆内存较大(如超过8G),可以考虑使用G1或ZGC,它们对于大堆和可预测的停顿有更好的表现。例如,为G1设置一个合理的预期停顿时间:-XX:+UseG1GC -XX:MaxGCPauseMillis=200。

内存问题的排查,最终是一场与复杂性和不确定性的博弈。没有银弹,最好的武器是清晰的监控、科学的分析工具和对系统运行原理的深刻理解。每次解决一个棘手的OOM,不仅是修复了一个Bug,更是对系统认知的一次升级。下次当你再看到那个令人心悸的OutOfMemoryError时,希望你能从容地打开工具包,像一位经验丰富的侦探,一步步揭开表象,直抵问题核心。记住,预防永远胜于治疗,在代码编写和架构设计之初,就考虑到对象生命周期和资源管理,往往能省去线上排查的无数不眠之夜。

深入解析OOM内存溢出:从原理到实战排查与优化 内存溢出(Out Of Memory,简称OOM)是程序运行时常见且棘手的问题,其本质是程序在申请内存时,系统无法提供足够的连续空间。理解其原理需要从内存管理的基础概念入手,现代编程语言的运行时环境通常将内存划分为堆、栈、方法区等逻辑区域,垃圾回收(GC)机制负责自动回收不再使用的对象。OOM的发生往往意味着内存泄漏或资源管理不当,其技术价值在于保障应用的稳定性和资源利用率。在应用场景上,无论是处理大数据的后端服务,还是像VSCode这样的桌面开发工具,都可能遭遇OOM困扰,例如近期频繁出现的“vscode 阅读详情

相关推荐

Java中的OutOfMemoryError(OOM)

OutOfMemoryError(OOM)是Java虚拟机(JVM)在无法分配足够内存时抛出的严重错误,通常导致应用程序崩溃。OOM与系统级内存不足不同,主要影响单个JVM进程,可通过JVM参数调整。常见的OOM类型包括Java堆OOM、元空间OOM、直接内存OOM等,每种类型对应不同的内存区域和触发条件。OOM的根本原因可能包括内存泄漏、内存溢出、JVM配置不当或外部因素。诊断OOM时,可以使用命令行工具(如jps、jstat、jmap)或图形化工具(如JConsole、VisualVM)进行分析,并通过

记录学习的过程 1824

线上问题的排查之内存溢出(OOM)问题如何排查

和往期性能优化类文章一样,步骤基本上大差不差 ,查找日志,分子日志,定位问题,审核代码,优化代码。并进行测试验证,一般就在测试环境进行测试,不要在正式进行,避免出现生产事故。

qq_39126115的博客 2402

53期-如何排查JVM在微服务架构下的OOM问题

OOM 是 “Out of Memory” 的缩写,指的是计算机或其他设备在尝试分配内存时,发现可用内存不足,无法满足请求的情况。OOM 错误通常会导致程序崩溃或者系统运行变慢,甚至可能导致整个系统出现不稳定的情况。导致OOM问题的原因通常有两个:1、内存泄露,一般是由于代码导致的,使用完的对象内存没有及时释放,越累计越多,最终耗尽内存2、内存需求过大,某些操作或数据结构需要大量内存。例如,加载非常大的文件、处理大规模数据集或者创建大量对象。

你不是叶秋的博客 863

OOM 场景及排查手段

Java 应用中的 OOM(Out Of Memory,内存溢出) 是常见的运行时错误,涉及多种场景和原因。常见的 OOM 类型包括 Java heap space、GC overhead limit exceeded、Metaspace、unable to create new native thread、Direct buffer memory 和 Out of swap space。每种类型的原因和排查手段不同,如堆内存不足、GC 效率低、类加载过多、线程数超限、堆外内存不足或本地内存泄漏等。排查时可

红血哥 1132

Java与Go内存溢出(OOM)排查与优化实战指南

内存溢出(OOM)是Java和Go开发者面临的常见性能问题,其本质是程序申请的内存超过了系统可用资源。Java通过JVM的垃圾回收机制(GC)管理内存,而Go采用基于协程的轻量级内存模型,两者的OOM特征和排查方法各有特点。理解内存管理原理对构建高可用系统至关重要,尤其在电商促销、实时交易等高压场景下。通过MAT、pprof等工具分析Heap Dump和内存快照,可以快速定位内存泄漏点。结合Prometheus监控和防御性编程实践,能有效预防OOM问题。本文通过实战案例,详解Java的Metaspace泄漏

weixin_30983353的博客 228

别再手动上传了!用宝塔面板的‘Let‘s Encrypt’免费SSL证书,3分钟自动续期

本文详细介绍了如何利用宝塔面板的‘Let‘s Encrypt’功能实现SSL证书的自动申请和续期,3分钟完成配置即可永久免费使用。通过对比不同SSL证书方案,突出Let's Encrypt的免费、自动续期和高安全性优势,特别适合个人博客和中小企业官网。

weixin_30415113的博客 150

Docker 容器 OOM:从资源监控到JVM调优的实战记录

在微服务架构盛行的今天,Docker容器化部署已经成为标准实践。然而,在之前生产环境部署中,我遭遇了一个让人头疼的问题:Java应用在Docker容器中频繁出现OOM(Out of Memory)错误,导致服务不断重启,严重影响了用户体验。这个问题的复杂性远超我的预期。表面上看是简单的内存不足,但深入分析后发现,这涉及到Docker容器的资源限制机制、JVM内存管理策略、以及容器环境下的内存分配逻辑等多个层面。更让人困惑的是,同样的应用在物理机上运行良好,但一旦容器化部署就会出现内存问题。

Rqaqedamancy的博客 3万+

SecureCRT 9.0最新版安装与激活全攻略(附驱动识别技巧)

本文提供SecureCRT 9.0最新版的详细安装与激活指南,并重点解析了嵌入式开发中串口连接的硬件驱动识别技巧。内容涵盖从安全获取软件、解决USB转串口驱动兼容性问题,到配置SSH与串口会话的完整流程,旨在帮助开发者和工程师高效部署并精通使用这款终端仿真利器。

star的博客 414

OOM问题排查及原因解析

一、前言 最近公司线上出了故障,有业务反馈说线上某台机器发出的请求status都是101,代表是超时。于是顺着调用栈和监控去查,最后发现这台机器上的网关挂掉了,所以导致请求发不出去,导致业务超时。那为啥无缘无故的网关挂掉了呢,顺着各种系统日志去查,结合机器是mq消费脚本专用机器,最后从系统日志/var/log/messages中查到如下日志 ... Out of memory: Kill p...

藏经阁 1万+

基于Arduino的智能垃圾桶

通过本次简单的Arduino智能垃圾桶小实验可以快速了解Arduino的基本用法 1、材料准备 Arduino UNO HC-SR04超声波模块 SG90舵机 杜邦线 电源 电脑 2、代码分析 电机的控制 #include<Servo.h> #define duoji D5 Servo myduoji; void setup() { myduoji.attach(duoji); //舵机连接 Serial.begin(115200); } void loop() { myduoji.w

weixin_41679960的博客 1万+

基于CNN对抗嵌入的图像隐写——CNN-Based Adversarial Embedding for Image Steganography

CNN-Based Adversarial Embedding for Image Steganography https://ieeexplore.ieee.org/abstract/document/8603808 这篇论文发表在TIFS( IEEE TRANSACTIONS ON INFORMATION FORENSICS AND SECURITY),TIFS是网络与信息安全领域的国际两大顶级期刊之一,中国计算机学会(CCF)推荐的A类期刊,SCI一区TOP期刊,目前影响因子有7多了。 1 概

weixin_48654804的博客 2279

Java线上环境OOM问题排查

这次跟大家分享的是如何解决线上环境OOM问题

2744

无人机核心部件解析:从机架到飞控的全面指南

本文全面解析无人机的核心部件,从机架材质选择到飞控系统调参,提供专业指南。重点介绍碳纤维机架、无刷电机搭配、锂聚合物电池管理及飞控传感器配置,帮助读者掌握无人机组装与优化的关键技术,适用于航拍、测绘、农业植保等多种应用场景。

weixin_30872499的博客 472

《JVM如何排查OOM》

理解JVM内存模型和各区域作用熟练使用各种诊断工具建立系统化的排查思路积累常见场景的解决经验重视预防和监控,而非仅事后补救记住:好的开发者不是不会遇到OOM,而是能够快速定位和解决OOM问题。希望本文能帮助你在遇到OOM时不再恐慌,而是有条不紊地解决问题。

2301_81117855的博客 1441

深入理解光流法外推雷达回波

背景介绍 鉴于本人实在太过疲惫和劳累,一些简单的便于理解的废话就不在记录,耗费两天时间研究了一下光流法,本帖用于记录学习过程中源码的难点细节。 使用光流预测的核心有两个利用多张连续回波图像(变分)或者相邻两张回波图(交叉相关,LK等)计算出光流场(速度矢量场),之后利用半拉格朗日方法进行外推。 半拉格朗日方法 三时间步半拉格朗日方法,其核心公式如下 但这个有点难理解,但看一维的图就很好理解 它的核心就是迭代求Am(位移矢量),如果理解困难的话,其实质上就是通过未来迭代(猜)出当前时刻的Am找到过去的假设

weixin_44695861的博客 6036

MatterPort3D 数据集下载

【代码】MatterPort3D 数据集下载。

qq_44106838的博客 6786

线上OOM了,怎么排查?

描述:在 Java 8 之前,方法区(PermGen)用于存储类的元数据,当 PermGen 空间不足时,会抛出 java.lang.OutOfMemoryError: PermGen space。使用监控工具:使用监控工具(如 Prometheus、Grafana、JVisualVM、JConsole 等)监控应用的内存使用情况,查看内存的使用趋势。生成堆转储:在应用运行时定期生成堆转储(Heap Dump),并使用分析工具(如 Eclipse MAT)分析内存使用情况,查找潜在的内存泄漏。

sunsiny 1022

rk3576 适配摄像头 (mipi 五摄)

在RK3576上实现五路CSI摄像头方案,核心思路是充分复用其视频输入接口,并通过巧妙的软件配置来实现。

weixin_35723192的博客 185

JVM OOM问题如何排查和解决

在 Java 开发中,**JVM OOM(OutOfMemoryError)**问题通常是指程序运行时,JVM 无法为对象分配足够的内存空间,导致发生内存溢出的错误。这个问题往往和内存的配置、内存泄漏、或者资源过度使用等因素有关。JVM 中的 OOM 错误主要包括以下几种类型:排查 OOM 问题可以从以下几个角度入手:通过 JVM 参数 来查看堆内存的大小和使用情况。常用的 JVM 参数有:通过这些参数可以定位内存是否足够,堆内存是否被频繁的垃圾回收占满。可以通过一些可视化的工具来监控 JVM 的内存使用情

有时间就写写代码 1413

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

线上JVM OOM问题,如何排查和解决?

JVM OOM 是一个复杂但常见的问题,它可能出现在堆内存、永久代/元空间、栈内存或直接内存等区域。排查 OOM 的关键在于启用诊断选项(如堆转储和 GC 日志)、分析错误日志和堆转储文件、检查垃圾回收日志。解决 OOM 的方法包括增加内存、优化代码、调优垃圾回收器参数和管理外部资源。持续监控和预警机制可以有效预防 OOM 问题的发生。希望这篇文章能帮助你在面试中更好地回答 OOM 相关问题,也能在实际工作中解决类似问题。如果你在工作中也遇到过 OOM 问题,欢迎在评论区留言,我们一起交流经验。

weixin_66137383的博客 2756

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

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

彻底吃透 Java OOM 异常:从原理、场景、排查到解决方案全攻略

OOM 全称JVM 无法为新对象分配内存,且垃圾回收也无法腾出足够空间,最终抛出的致命错误。OOM 是Error,不是 Exception,一旦出现,应用基本不可用。不是 “内存不够”,而是内存被占满、且回收不了。90% 的 OOM 不是 JVM 内存太小,而是代码问题。OOM =内存满了,新对象没地方分配最常见,大多是没分页、内存泄漏Metaspace溢出 = 类太多溢出 = NIO/Netty 问题= 递归 / 调用太深无法创建线程= 线程太多。

2301_82132279的博客 1488

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

内存溢出OOM的问题排查流程

Mat内存分析内存溢出问题

qq_16369559的博客 4324

一次OOM 排查与修复实战:从 MAT 报告到代码优化

文章摘要:最近测试环境出现了一起频繁的 OOM(OutOfMemoryError)异常,导致服务频繁重启,影响了业务正常运行。经过一系列排查、分析与优化,最终解决了问题。今天就把整个过程梳理下来,分享给大家,希望能给遇到类似问题的同学提供一些参考。

dhdhd78273的博客 421

线上项目报错OOM常见原因、排查方式、解决方案

(OOM)是 Java 应用程序中常见的问题,通常是由于应用程序占用的内存超过了 JVM 分配的最大内存限制。在 Spring Boot 项目中,OOM 问题可能由多种原因引起。1. OOM 的常见原因1.1 内存泄漏(Memory Leak)对象被意外地长时间持有,导致无法被垃圾回收(GC)。常见场景:静态集合类(如static Map)持续增长。未关闭的资源(如数据库连接、文件流)。缓存未设置过期时间或大小限制。1.2 堆内存不足应用程序需要的内存超过了 JVM 堆内存的最大限制(通过-Xmx。

a_beiyo的博客 2591

怎么排查OOM? 都有哪些可能导致的原因? 怎么解决?

OOM异常是一个常见的问题。为了避免OOM异常,我们需要了解可能导致OOM异常的原因,并采取相应的措施来解决问题。例如,我们可以使用内存分析工具来查看Java应用程序的内存使用情况,使用线程池来管理线程,使用缓存来提高性能,或者使用分布式系统来处理大量的数据。通过这些措施,我们可以避免OOM异常的发生,提高Java应用程序的性能和稳定性。

果酱 の 博客 2923
上一篇: 手机相机实验室测试全攻略:从AWB到ISP的完整流程解析
下一篇: Win11家庭版夜间自动关机?3步排查+修复方案(附bat脚本)
普通网友
博客等级 码龄27年 205粉丝 1502原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值