用 newFixedThreadPool 跑导入任务,堆内存一路涨到 OutOfMemoryError,线程数却始终稳定在 8 个。乍看像缓存或者权限的锅,追下去往往不是。

new ThreadPoolExecutor(8, 16, 60L, TimeUnit.SECONDS,
    new ArrayBlockingQueue<>(200),
    new ThreadPoolExecutor.CallerRunsPolicy());

追下去是这么回事:这个工厂方法的队列是 LinkedBlockingQueue 且没有容量上限,任务只进不出,堆被待执行任务撑爆。

「无界队列堆积」相关的验证我通常做两遍,改完一次、隔天再看一次,确认不是临时生效。接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。

偶发问题先统计频率,一小时几次和一天一次,查法完全不同。改完顺手把文档补一句,省得下次自己重新推一遍。

监控和日志的时间要对上,时区不一致会多绕很大一圈。临时改动用注释写上日期和原因,过两周自己都记不清为什么这么写。

动手前把原文件复制一份带时间戳,出问题立刻换回去,比现场分析快得多。

具体做法是,改用 ThreadPoolExecutor 显式传有界队列;给队列设容量并配拒绝策略;导入任务改成分批提交。

验收就看一点,压测时队列长度有上限,堆内存回落且不再出现 OOM。

作者 9823189