又踩坑了系列…
得到反馈管理端一个返回系统基本权限数据的接口服务端异常了。查看错误日志:
竟然是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;
}
|
这里犯了一个致命的问题 – 线程池使用完未关闭。改进修改这个问题,增加线程池关闭:
如果线程池不关,那线程池是不会自动销毁的。也就是每次调用请求都会创建coreSize个线程,时间久了肯定会造成OOM。
啊 … 我真蠢。
- 本文链接:https://gsmtoday.github.io/2020/03/23/threadpool-oom/