线程池不关闭引发的OOM血案

又踩坑了系列…
得到反馈管理端一个返回系统基本权限数据的接口服务端异常了。查看错误日志:


竟然是OOM,Java应用程序已达到其可以启动线程数量的极限了。肯定是有地方创建了太多线程,消耗光了系统的线程数。
Caused by: 
java.lang.OutOfMemoryError: unable to create new native thread

由于线上机器已经漂移重建,无法查看堆栈现场。使用测试环境看下线程数(因为运行情况差不多,在一定情况是可以反应线上环境的)。


竟然有1w多个waiting线程。

然后和同事定位代码。发现问题代码集中在:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Override
public Integer getPermissionCount(Long appId) {
    ExecutorService es = Executors.newFixedThreadPool(4);
    CompletionService<Integer> cs = new ExecutorCompletionService<>(es);
    cs.submit(() -> flagService.getFlagCount(appId));
    cs.submit(() -> roleService.getRoleCountByAppId(appId));
    cs.submit(() -> featureService.getFeatureCountByAppId(appId));
    cs.submit(() -> areaService.getAreaCountByAppId(appId));

    Integer result = 0;
    for (int i=0; i<4; i++) {
        try {
            Integer permissionCount = cs.take().get();
            result = result + permissionCount;
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
    return result;
}

这里犯了一个致命的问题 – 线程池使用完未关闭。改进修改这个问题,增加线程池关闭:

1
es.shutdown();

如果线程池不关,那线程池是不会自动销毁的。也就是每次调用请求都会创建coreSize个线程,时间久了肯定会造成OOM。

啊 … 我真蠢。

  • 本文链接:https://gsmtoday.github.io/2020/03/23/threadpool-oom/
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值