当前位置: 首页 > news >正文

任务堆积导致 OOM(内存溢出)

文章目录

  • 任务堆积导致 OOM(内存溢出)
    • 问题描述
    • 错误实现
    • 正确实现

任务堆积导致 OOM(内存溢出)

问题描述

使用无界队列(如 LinkedBlockingQueue)的线程池,在任务提交速率远高于处理速率时,队列无限堆积,最终导致内存溢出(OOM)。

错误实现

public class QueueOOMDemo {

    // 静态集合防止GC回收内存(加速OOM)
    private static final List<byte[]> memoryHolder = new ArrayList<>();

    public static void main(String[] args) {
        // 使用无界队列(快速堆积大对象)
        ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4, 60, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>());

        // 提交大量任务,每个任务分配2MB内存(加速内存消耗)
        for (int i = 0; i < 20000; i++) {
            executor.execute(() -> {
                // 分配2MB内存,并存入静态集合防止GC回收
                byte[] chunk = new byte[2 * 1024 * 1024];
                synchronized (memoryHolder) {
                    memoryHolder.add(chunk);
                }
                // 模拟任务耗时
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
    }
}

运行结果

Exception in thread "pool-1-thread-2" Exception in thread "pool-1-thread-3" Exception in thread "pool-1-thread-1" Exception in thread "pool-1-thread-4" Exception in thread "pool-1-thread-6" Exception in thread "pool-1-thread-5" Exception in thread "pool-1-thread-7" Exception in thread "pool-1-thread-8" java.lang.OutOfMemoryError: Java heap space
    at com.szkingdom.example.thread01.QueueOOMDemo.lambda$main$0(QueueOOMDemo.java:30)
    at com.szkingdom.example.thread01.QueueOOMDemo$$Lambda$1/897913732.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Exception in thread "pool-1-thread-12" java.lang.OutOfMemoryError: Java heap space
Exception in thread "pool-1-thread-13" java.lang.OutOfMemoryError: Java heap space

问题分析

- 无界队列风险:默认队列容量为 `Integer.MAX_VALUE`,任务无限堆积,直至内存耗尽。
- OOM类型:通常为 `GC overhead limit exceeded` 或 `Java heap space`。

正确实现

  • 限制队列容量:使用有界队列,防止任务无限堆积。
  • 合理拒绝策略:任务满时触发拒绝策略,避免内存溢出。
public class QueueOOMFixedDemo {
    public static void main(String[] args) {
        // 使用有界队列(容量1000)和拒绝策略
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
            2, 4, 60, TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(1000), // 队列容量1000
            new ThreadPoolExecutor.AbortPolicy()
        );

        try {
            for (int i = 0; i < 20000; i++) {
                executor.execute(() -> {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                });
            }
        } catch (RejectedExecutionException e) {
            System.err.println("任务被拒绝,已提交任务数:" + executor.getTaskCount());
        }

        executor.shutdown();
    }
}

运行结果

任务被拒绝,已提交任务数:1004
http://www.dtcms.com/a/107620.html

相关文章:

  • 08-MySQL InnoDB锁的基本类型
  • 【前端】电脑初始安装软件工具
  • 【Linux】内核驱动学习笔记(一)
  • 【论文笔记】DeepSeek-R1 技术报告
  • java虚拟机---JVM
  • python实战案例:财务凭证数据分析和生成报告
  • .net 6 + vue3中使用SignaIR实现双向通信功能
  • 界面架构 - MVVM (Qt)
  • 准确--回顾B站 “713“ 大规模服务不可用事故
  • 合并有序链表
  • 致敬生物信息学先驱:玛格丽特·戴霍夫(Margaret Dayhoff,1925-1983)
  • 多分类交叉熵
  • AIP-211 授权检查
  • transformer结构原理
  • Unity开发——Destory延迟销毁导致异常的处理
  • 关于 数据库 UNION 和 UNION ALL 的使用,以及 分库分表环境下多表数据组合后的排序和分页问题的解决方案 的详细说明,并以表格总结关键内容
  • 【黑科技护航安全】分布式光纤测温:让隐患无处可藏
  • Vite 内联 CSS 和 JS 的解决方案
  • 机器学习的一百个概念(7)独热编码
  • 大文件上传源码,支持单个大文件与多个大文件
  • 【三层架构有哪些?】
  • 函数fcntl(File Control)
  • spring AOP 事务 过滤器(Filter)与拦截器(Interceptor)
  • java项目分享-分布式电商项目附软件链接
  • C语言变长数组(VLA)详解:灵活处理动态数据的利器
  • 【大模型系列篇】大模型基建工程:使用 FastAPI 构建 MCP 服务器
  • 智能语音识别工具开发手记
  • Java 枚举类 Key-Value 映射的几种实现方式及最佳实践
  • 【Framework-Client系列】UIGenerate介绍
  • MTK AWB 色温曲线的进一步猜想