请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

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

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

业务场景是这样的:

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回答

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

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

0 回复 有任何疑惑可以回复我~
  • 提问者 Screenly #1
    非常感谢!
    回复 有任何疑惑可以回复我~ 2020-10-28 22:24:25
  • 提问者 Screenly #2
    嗯嗯,谢谢老师回复,我是用了每次分页查询之后,每页5W条记录,使用了CountDownLatch, 结合用线程池,每5万条记录使用线程池去完成,再进行下一页的5W条,cpu和内存都合理的使用起来了,谢谢老师!!
    回复 有任何疑惑可以回复我~ 2020-10-28 22:26:47
  • 悟空 回复 提问者 Screenly #3
    太棒了
    回复 有任何疑惑可以回复我~ 2020-10-29 10:00:39
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信