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

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

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

文章插图
 
竟然是OOM,JAVA应用程序已达到其可以启动线程数量的极限了 。肯定是有地方创建了太多线程,消耗光了系统的线程数 。
Caused by:
java.lang.OutOfMemoryError: unable to create new native thread
由于线上机器已经漂移重建,无法查看堆栈现场 。使用测试环境看下线程数(因为运行情况差不多,在一定情况是可以反应线上环境的) 。
线程池不关闭引发的OOM血案

文章插图
 
竟然有1w多个waiting线程 。
然后和同事定位代码 。发现问题代码集中在:
12345678910111213141516171819202122@Overridepublic 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;} 【线程池不关闭引发的OOM血案】这里犯了一个致命的问题 – 线程池使用完未关闭 。改进修改这个问题,增加线程池关闭:
1es.shutdown(); 如果线程池不关,那线程池是不会自动销毁的 。也就是每次调用请求都会创建coreSize个线程,时间久了肯定会造成OOM 。
啊 … 我真蠢 。
  • 本文链接:https://gsmtoday.github.io/2020/03/23/threadpool-oom/




    推荐阅读