线程池用了LinkedBlockingQueue没设容量,把整台机器搞OOM了
凌晨运维群炸了,一条告警:订单服务响应超时率飙到 80%,紧接着 JVM 挂掉,Pod 重启。 上去一看,OOM 前老年代被打满了。heap dump 里最大的对象是一个 LinkedBlockingQueue,里面堆了 300 多万个任务对象,光队列就占了将近 2G。 翻代码,线程池是这么配的: ExecutorService executor = new ThreadPoolExecutor( 10, // corePoolSize 20, // maximumPoolSize 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>() // ← 没设容量,默认 Integer.MAX_VALUE ); 10 个核心线程忙不过来的时候,任务进了队列。队列没有上限,上游的定时任务每 10 毫秒投递一个任务,半小时就塞了 300 万个。 线程在消费,队列在膨胀——消费速度跟不上生产速度,OOM 只是时间问题。 这就是 LinkedBlockingQueue 最坑人的地方:默认构造是无界的。 一、为什么无界队列是定时炸弹 new L....