又踩坑了系列…
得到反饋管理端一個返回系統基本權限數據的接口服務端異常了。查看錯誤日志:
竟然是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/