You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何排查容器内存溢出(OOM)根本原因?Micronaut批量任务触发137退出码

退出码137本质是进程被操作系统的OOM Killer强制终止,通常是进程占用内存超过了cgroup限制。你没有生成JVM堆转储,说明OOM发生在JVM堆外或者操作系统层面,而非JVM堆内存溢出,可以按以下方向排查:

  • 修复JDBC ResultSet全量拉取问题
    你当前的代码没有设置fetchSize,绝大多数JDBC驱动默认会一次性将全部50万条查询结果加载到进程内存中,哪怕你按100条批次消费,这部分内存占用会直接打满容器。修复方式:
  1. 执行查询前设置statement的拉取批次大小:
statement.setFetchSize(batchSize);
  1. 如果你使用的是MySQL驱动,需要额外在JDBC连接URL中添加参数useCursorFetch=true,否则fetchSize配置不生效。
  • 调整JVM内存配置,避免超出容器限制
    容器512M内存需要同时覆盖JVM堆、JVM元空间、堆外内存、操作系统进程基础开销,不能将JVM堆设得过高:
  1. 添加JVM参数指定堆上限:-Xmx384m -Xms384m,预留128M给堆外内存和系统开销
  2. 显式限制堆外内存上限:-XX:MaxDirectMemorySize=64m,如果后续出现堆外内存OOM会抛出明确报错,方便定位
  • 排查业务逻辑内存泄漏
  1. 检查consumer.accept的处理逻辑:是否有全局静态集合持有了所有批次的ItemEntity对象未释放,API调用的HTTP客户端是否存在连接未关闭、请求/响应体资源未释放的问题
  2. 检查SQLite写入逻辑:是否存在批量写入缓存未按时提交、驱动资源未释放的问题
  • 实时监控内存变化定位峰值
    运行批量任务的同时执行docker stats <容器ID>,观察容器内存占用的变化曲线:如果拉取数据阶段内存直接飙升到512M,就可以确认是ResultSet全量拉取的问题;如果内存是在处理批次过程中缓慢上涨,就是业务逻辑存在内存泄漏。

  • 临时放大容器内存验证根因
    可以先将容器内存限制调整到1G,如果任务可以正常运行,说明问题本质就是内存不足,再针对性做内存优化即可。


内容的提问来源于stack exchange,提问作者Manish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 21:06:03