线程池用完之后如何回收避免内存一直飙升

来源:3-5 用法演示

Screenly

2020-10-21

悟空老师,目前手上有一个问题,想请教一下

业务场景是这样的:

1. 需要在阿里云RDS的MySQL中, 在2小时内解析完200W的订单,整个过程只是把一串订单JSON串拆解为多个字表进行存储
2. 分页查询,一页【5w】条数据,一共【45】页,并使用`newFixedThreadPool`这种类型的线程池, 服务器内存8G,然后内存一直往上飙 ,直到OOM

伪代码如下

private final static ExecutorService executor1 = Executors.newFixedThreadPool(4);
// 分页...
for (int i=1; i < 总页数; i++) {
	List<json对象> orderList = db.selectList();// 分页的查询, 
	orderList.parallelStream().forEach(obj -> {
		executor1.execute(() -> {
			// 拆解订单json串 并 更新到数据库
		});
	});
}

产生的现象

使用了 newFixedThreadPool 这种类型的线程池,使用的时候内存一直往上走, 直到OOM或者卡死机,

提问

1.请问一下老师这种业务场景有没有更好的处理方式,
2.线程池用完之后内存会不会自己降回来
3.用了线程池,确实速度很快,但是内存一直飙升,很慌

写回答

1回答

悟空

2020-10-22

内存飙升因为任务都放到队列中了,这样大量数据的情况,需要自定义线程池,限定队列的长度,然后拒绝策略可以试试CallerRunsPolicy,可以防止内存飙升。

线程池用完之后内存会不会自己降回来:会

0
3
悟空
回复
Screenly
太棒了
2020-10-29
共3条回复

深度解密Java并发工具,精通JUC,成为并发多面手

JUC全方位讲解,构建并发工具类知识体系

1599 学习 · 573 问题

查看课程