该程序后期会不断 GC,但是又无法回收多少内存,最终可能会 OOM
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 从数据库中读取信用数据,套用模型,并把结果进行记录和传输
*/
public class T15_FullGC_Problem01 {
private static class CardInfo {
BigDecimal price = new BigDecimal(0.0);
String name = "张三";
int age = 5;
Date birthdate = new Date();
public void m() {}
}
private static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(50,
new ThreadPoolExecutor.DiscardOldestPolicy());
public static void main(String[] args) throws Exception {
executor.setMaximumPoolSize(50);
for (;;){
modelFit();
Thread.sleep(100);
}
}
private static void modelFit(){
List<CardInfo> taskList = getAllCardInfo();
taskList.forEach(info -> {
// do something
executor.scheduleWithFixedDelay(() -> {
//do sth with info
info.m();
}, 2, 3, TimeUnit.SECONDS);
});
}
private static List<CardInfo> getAllCardInfo(){
List<CardInfo> taskList = new ArrayList<>();
for (int i = 0; i < 100; i++) {
CardInfo ci = new CardInfo();
taskList.add(ci);
}
return taskList;
}
}
1
senninha 2020-08-03 18:30:35 +08:00
CardInfo 一个都回收不了,这不就内存泄漏了。
|
2
ChanKc 2020-08-03 19:09:32 +08:00 via Android
一直都在加 cardinfo 而且 executor 来不及执行所以越来越多?
|
3
LudwigWS OP @senninha
请问一下为什么 CardInfo 回收不了?线程池满了以后旧的任务被抛弃了,按理说垃圾回收器不是能回收了么。 |
4
airfling 2020-08-03 19:36:12 +08:00
回收不了的,CardInfo 被 Runnable 隐式调用,ScheduledThreadPoolExecutor 你看的是核心线程是 50,但是任务队列应该是无线大的
|
5
yannxia 2020-08-03 19:46:11 +08:00
cardinfo 在 threadpool 的 queue 里面了,虽然都没有实际调用,但是的确是越来越多的。调整 scheduleWithFixedDelay 的速度 或者把 queue 改小。
|
6
asd123456cxz 2020-08-03 20:09:08 +08:00
ScheduledThreadPoolExecutor 使用的是 DelayedWorkQueue,它在提交队列到容量上限时会进行扩容,即不会触发 discard 。
仅看了下源码,没有验证,有问题请指正 |